Xcode 7 and NS_DESIGNATED_INITIALIZER

When I complie my project with Xcode 7 i have new compiler errors

Method override for the designated initializer of the superclass '-init' not found


suggest that NSObject init is marked as designeted initializer.


My class look like this:

- (nullable instancetype)initWithModel:(nonnull Model *)model
                                  view:(nonnull UIView *)view NS_DESIGNATED_INITIALIZER;


This object is initialize with view and model that is used to controll it. It's shoudn't exist without any of it, that why it has nonull.

The view is created from storyboard, model comes from CoreData.


My question is, how should I handle the requried init?


Something like this make my code to complie but I doesn't have any sense.

- (instancetype)init {
     Model *model = [Model new];
     View *view = [View new];
     self = [self initWithModel:model view:view];
     return self;
}

Accepted Reply

The rules for designated initialisers are complex and I'm going to bounce you to the docs for the general case. Curiously, I've found the best explanation of this to be the "Initialization" section of The Swift Programming Language, because the same concepts apply to both Swift and Objective-C.

In your specific case you should override -init and have it fail at runtime. You should also tag it in your header with NS_UNAVAILABLE which will allow the compiler to catch this in the typical case.

The above applies because your class can't possibly operate without a Model, and thus you can't reasonably implement -init in any useful way. If you could, you should. For example, if you were creating your own string object, it would make sense for it to implement -init by calling super and then initialising the string to the empty string.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1@apple.com"

Replies

The rules for designated initialisers are complex and I'm going to bounce you to the docs for the general case. Curiously, I've found the best explanation of this to be the "Initialization" section of The Swift Programming Language, because the same concepts apply to both Swift and Objective-C.

In your specific case you should override -init and have it fail at runtime. You should also tag it in your header with NS_UNAVAILABLE which will allow the compiler to catch this in the typical case.

The above applies because your class can't possibly operate without a Model, and thus you can't reasonably implement -init in any useful way. If you could, you should. For example, if you were creating your own string object, it would make sense for it to implement -init by calling super and then initialising the string to the empty string.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1@apple.com"

Privately implement the superclass initializer and make it throw.


In MyClass.h:

@interface MyClass : NSObject
- (instancetype)init NS_UNAVAILABLE;

...
@end


In MyClass.m:


@interface MyClass ()
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end

@implementation MyClass
- (instancetype)init { @throw nil; }


...
@end