Overriding initialize()
is common for executing code before a class is sent its first message (setting UserDefaults, etc). The documentation states that a superclass' implementation may be called multiple times subclasses do not override initialize()
, and give an example of a way to protect a class from executing code more than once if initialize()
is called several times:
The superclass implementation may be called multiple times if subclasses do not implement
initialize()
—the runtime will call the inherited implementation—or if subclasses explicitly call[super initialize]
. If you want to protect yourself from being run multiple times, you can structure your implementation along these lines:+ (void)initialize { if (self == [ClassName self]) { // ... do the initialization ... } }
I am overriding initialize()
in my AppDelegate and trying to avoid having code run more than once. The class check doesn't make sense to me, as checking if self is AppDelegate.Type
will always evaluate to true (and gives me a warning in Xcode).
Does the class check not apply, since we're not in a superclass (the superclass of AppDelegate
is UIResponder
)? Will the contents of my overridden initialize()
method only run once without calling super
or performing a class check?
The reason for the class check is because you usually want to run code on
initialize
only once (as per the docs). Writing that condition protects you from subclasses that don't implementinitialize
or call[super initialize]
. Here's an example class hierarchy:When I instantiate a new
Dog
, the Objective-C runtime will send theinitialize
method to every class inDog
's hierarchy (superclasses first), soDog
will receive the message, but so willAnimal
. BecauseDog
doesn't implementinitialize
, its superclass will receive the message, so if you don't add the check that makes sure that the message was intended for that class, your code will end up executing twice.This doesn't really make sense in Swift, and probably even less so in an AppDelegate so if you want to have code only run once in Swift, you should probably use lazily initialized globals or static properties, as defined in the migration docs.