Search code examples
objective-cinitializationsubclassinitdesignated-initializer

Designated Initializer, clarify please.


Now i have had this problem clouding my mind for quite sometime and i really need someone to clarify this for me.

1) how is a designated initializer method determined by the compiler when it is called on by a subclassed init method? as it is said to be the one with the most coverage.

2) when subclassing with multiple init methods, does each class have its own designated initializer method? Answer to question 2 would add to the assist of understanding this as well.

3) When multiple classes do have a designated initializer how do the other init methods invoke the designated initializer in their class? and how come they don't invoke any other initializer as well? why the designated initializer? whats so special about it?


Solution

  • In Objective-C, the designated initializer of a class is the method that's responsible for properly initializing the class to put it in an appropriate state for use. There is nothing in the code that marks it as the designated initializer, so there is usually a comment in the header file for that. It is up to the developer who is using or extending that class to figure out which method is the designated initializer (usually init or prefixed with init) and to write code accordingly. This can lead to mis-use of a class if it is not properly documented and its source code is not available and is one of the shortcomings that Swift attempts to solve. So to address your questions...

    1. A designated initializer is not determined by the compiler. A subclass should also have a designated initializer that calls the super's designated initializer at some point.
    2. Each class should clearly state (via comments or documentation) which initializer is intended to be used as the designated initializer. It is up to the developer who is using the class to make sure that the designated initializer is invoked. It is up to the developer of the class itself to ensure that the super's designated initializer is invoked as intended. However, with properly written classes, any of the init methods should invoke the designated initializer. However, it is not guaranteed by the compiler.
    3. Other init methods need to be coded appropriately to invoke the designated initializer via [self init...] or [super init...]. Again, it is up to you to figure out how a class is intended to be used and to use it or extend it appropriately.

    The designated initializer is the method that does the "heavy lifting" to prepare a new instance of a class for use. Other initializers are known as convenience initializers and are typically used to provide shorter signatures with implied defaults since you can't specify default parameter values for Objective-C method signatures.

    In most cases, if a class is properly written, you shouldn't really have to worry too much since all convenience initializers should end up invoking the designated one.

    A lot of thought was put into this during the development of Swift and even if you don't intend to learn it, you should read up on Swift Initializers as it will give you good insight into the proper chain of initialization that you could then use to guide you in creating initializers in Objective-C.

    UPDATE: Since Xcode 6, designated initializers can be marked as such, typically via the NS_DESIGNATED_INITIALIZER macro. This helps enforce properly written classes and is something that was brought back to Objective-C from Swift. Check out iOS Designated Initializers : Using NS_DESIGNATED_INITIALIZER.