Prevent lazy initialization of static var

Hi all,

if I declare a property as "static var" it apparently automatically gets initialized lazily, i.e., only at the time it is first used. Is there are way to prevent this?


class Features
{
  static var feature1 = Feature()
  static var feature2 = Feature()
  ..
}


-> as soon as the class Features is used, all init() of Feature should be called


Thanks,

Markus

Accepted Reply

From the Swift blog:


developer.apple.com/swift/blog/?id=7


"Swift uses the third approach [Initialize lazily, run the initializer for a global the first time it is referenced]. […] The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed"


You have to ask yourself why you think that the compile-time declaration should tell the compiler anything about the run-time timing of initialization. Also, when — in run-time terms — does "as soon as the class Features is used" happen? App launch? Class framework load? First instance init? Also, if it matter when Feature() is called, what order should feature1 and feature2 be initialized? What if they're in different class extensions? The answers to such questions aren't obvious, except in an artifically simple example.

Replies

From the Swift blog:


developer.apple.com/swift/blog/?id=7


"Swift uses the third approach [Initialize lazily, run the initializer for a global the first time it is referenced]. […] The lazy initializer for a global variable (also for static members of structs and enums) is run the first time that global is accessed"


You have to ask yourself why you think that the compile-time declaration should tell the compiler anything about the run-time timing of initialization. Also, when — in run-time terms — does "as soon as the class Features is used" happen? App launch? Class framework load? First instance init? Also, if it matter when Feature() is called, what order should feature1 and feature2 be initialized? What if they're in different class extensions? The answers to such questions aren't obvious, except in an artifically simple example.

Thanks for the quick answer. You are correct, there wouldn't be a good way to define the initialization time.


What I was trying to do was, on the one hand, to easily access these properties like:


if Features.feature1.active
{
...
}


and on the other hand, iterate over them to easily get a list of features. To do so, Feature.init() would register self in a central place.


My solution is now to manually create a list of all features:


let allFeatures = [feature1, feature2, ...]


I was hoping to avoid this extra code.

>> and on the other hand, iterate over them to easily get a list of features. To do so, Feature.init() would register self in a central place


Ideally, what would the iteration code look like? I've got a feeling that you'd end up with something that was bulkier, and possibly uglier, than your "manual" code.


Incidentally, you might find it more palatable to turn the problem on its head:


class Feature
{
static let allFeatures = [Feature(), Feature(), …]
static let feature1 = allFeatures[0]
static let feature2 = allFeatures[1]
…
}

for feature in Feature.allFeatures { … }

if Feature.feature1.active { … }


(I also "economized" by putting the statics in class Feature instead of a separate class.)

True... after removing the "automatic registration code", I ended up with a better readible solution.

Thanks again