带闭包的默认属性值使编译器可以重新编译所有文件 [英] Default property value with closure makes a compiler to recompile all files
问题描述
此源中的段落使用闭包或函数设置默认属性值,我们可以在其中找到示例
This source has a paragraph Setting a Default Property Value with a Closure or Function where we can find an example
以下是有关如何使用闭包提供默认属性值的基本概述:
Here’s a skeleton outline of how a closure can be used to provide a default property value:
class SomeClass {
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
}
嗯,我经常使用它...而且,我经常只更改一个符号就等待整个项目重新编译.今天,我发现这两个东西是相互关联的.
Well, I use it very often... Also, I often wait for the whole project to recompile after changing just one symbol. And today I have discovered that these two things are associated to each other.
让我们想象一下,我们有一些类,其中我们使用闭包和函数来设置一些默认属性
Lets imagine we have some class where we set some default properties with a closure and with a function
class Class1 {
let value: Int
init(_ value: Int) {
self.value = value
}
private lazy var lazyValueWithClosure: Int = {
return 1111
}()
private lazy var lazyValueWithFunction: Int = self.getValue()
private func getValue() -> Int {
return 2222
}
}
此外,我们在单独的文件中还有其他一些类,我们在其中使用上面的Class1
Also we have some other class in a separate file where we use the above Class1
class Class2 {
let value: Int
init(_ value: Int) {
self.value = value
_ = Class1(100)
}
}
和其他类在单独的文件中,我们在其中使用Class2
And some other class in a separate file where we use Class2
class Class3 {
let value: Int
init(_ value: Int) {
self.value = value
_ = Class2(100)
}
}
等等...
我决定使用terminal
+ xcodebuild
+ grep
来仅获取有关重新编译文件的信息.那是我用来获取编译信息的命令:
I've decided to use terminal
+ xcodebuild
+ grep
to get only info about recompiled files. That is the command I use to get compilation info:
xcodebuild -scheme Test -sdk iphonesimulator -arch x86_64 -configuration Debug build OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" | grep '^[0-9]\{1,20\}.[0-9]\{1,20\}ms.*init(_ value: Int)'
仅此而已.现在我们进入Class1
并将2222
更改为其他值.运行上面的命令并获得结果.
That is all for preparations. Now we go to Class1
and change 2222
to some other value. Run the above command and get a result.
0.1ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class1.swift:11:5 init(_ value: Int)
结果很好.使用功能设置默认值可以正常工作.我们更改了一个文件,仅编译了一个文件.
The result is good. Setting default value with functions works as expected. We have changed one file and only one file was compiled.
然后将值1111
从Class1
更改为其他值并运行命令.终端输出现在看起来像这样:
Then lets change the value 1111
from the Class1
to some other value and run the command. Terminal output now looks like this:
0.8ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class5.swift:11:5 init(_ value: Int)
0.3ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class1.swift:11:5 init(_ value: Int)
1.0ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class4.swift:11:5 init(_ value: Int)
0.3ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class3.swift:11:5 init(_ value: Int)
0.3ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class2.swift:11:5 init(_ value: Int)
所有类都已重新编译...现在,假设您有一个大项目,并且默认值闭包中的任何细微变化都会使您等待整个项目重新编译.
All the classes were recompiled... Now imagine that you have a large project and any small change in a default value closure makes you wait for the whole project to recompile.
问题:
- 原因是什么?
- 有人建议如何使用默认值闭包而不遭受重新编译的痛苦吗?
- 与本主题有关?
- What is the reason?
- Any suggestions how to use default value closures and not to suffer from recompilation?
- Related to this topic?
推荐答案
这是Swift编译器中的一个已知问题.问题是,一旦您使用了闭包或惰性属性,将对每个单个Swift文件进行类型检查.我已经写了一篇有关该主题的博客文章,您可以在此处找到.
This is a known problem in the Swift compiler. The issue is that once you use closures or lazy properties like this, every single Swift file will be type checked. I've written a blog post on this topic which you can find here.
这篇关于带闭包的默认属性值使编译器可以重新编译所有文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!