The default value of the property upon closing causes the compiler to recompile all files

This source has the paragraph Setting the default value of a property with a closure or function where we can find an example

Here is a skeleton diagram of how you can use closure 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 be recompiled after changing only one character. And today I discovered that these two things are related to each other.

Suppose we have a class where we set some default properties with closing and with 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 } } 

We also have another class in a separate file in which we use the above Class1

 class Class2 { let value: Int init(_ value: Int) { self.value = value _ = Class1(100) } } 

And another class in a separate file where we use Class2

 class Class3 { let value: Int init(_ value: Int) { self.value = value _ = Class2(100) } } 

etc.

I decided to use terminal + xcodebuild + grep to get only information about recompiled files. This is the command I use to get compilation information:

 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)' 

This is all for cooking. Now go to Class1 and change 2222 to another value. Run the command above and get the result.

 0.1ms /Users/iwheelbuy/Documents/recompile/Test/Classes/Class1.swift:11:5 init(_ value: Int) 

The result is good. Setting the default with functions works as expected. We changed one file and compiled only one file.

Then change the value of 1111 to Class1 to another value and run the command. The 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 classes have been recompiled ... Now imagine that you have a large project and any small change to the default closure keeps you waiting for the whole project to be recompiled.

Questions:

  • What is the reason?
  • Any suggestions on how to use default locks and not recompile?
  • Related to this section ?
+7
terminal xcode swift swift3 xcodebuild
source share
1 answer

This is a known issue in the Swift compiler. The problem is that after using closures or lazy properties like this, every Swift file will be type checked. I wrote a blog post on this topic where you can find it here .

+5
source share

All Articles