3

I wrote a Swift utility class in which I define several static methods and a private static constant. However, I wish this constant to be loaded immediately after the class is referenced for the first time, as opposed to lazily. The only thing I can think of doing is to reference the static constant in every single static function like this:

private static let myObserver: Observer = {
    let observer = Observer(actionToPerform: foo1)
    SomeOtherClass.register(observer)
    return observer
}()

static func foo1() {
    _ = myObserver
    ...
}

static func foo2() {
    _ = myObserver  
    ...
}

static func foo3() {
    _ = myObserver
    ...
}

//even more of a hassle:
static let myIntConstant: Int = {
    _ = myObserver
    return 5
} ()

.
.
.

However, that solution looks pretty ugly. Is there a cleaner way? Some sort of class initialization callback I can use?

Hans Brende
  • 7,847
  • 4
  • 37
  • 44

1 Answers1

4

Ok, I seem to have found a workable solution to my own question.

  1. Ensure that the class is a subclass of NSObject.
  2. Insert the following code:

override class func initialize() { 
     _ = myObserver
}

After doing this, the static constant is loaded immediately after the class is referenced, as desired.

Of course, this approach is limited by the fact that the class must be a subclass of NSObject, which may not be possible for all such classes. Any other potential drawbacks to this approach would be welcomed!

Hans Brende
  • 7,847
  • 4
  • 37
  • 44
  • 1
    Yeah, I was wrong in my original answer because naturally if you use Swift on iOS you must be able to inherit from NSObject and have access to initialize(). It does have a bit of a “magicky” feel to it if you ask me but it’s officially [documented](https://developer.apple.com/reference/objectivec/nsobject/1418639-initialize) and NSHipster [has](http://nshipster.com/method-swizzling/) some [articles](http://nshipster.com/method-swizzling/) on this it shouldn’t be too bad. – Anton Strogonoff Dec 12 '16 at 10:22
  • Seems to be not permitted in Swift anymore: `Method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift` – rshev Oct 25 '22 at 17:04