Is this true? Do we have to do this all the time?
Personally, I consider it a bad guideline. It is illogical to implement the superclass' designated initializer (to do anything meaningful) when you have specified a stricter designated initializer (e.g. one which introduces a parameter).
For example, -initWithDomain:code:userInfo:
is NSError
's designated initializer; Could [[NSError alloc] init]
return a reasonably descriptive error?
If anything, privately override the 'deleted' initializer and treat it as an programmer error to call, but do not pretend that it is acceptable for a client to use an initializer other than a designated initializer.
Note that your class will in some cases be able to support both initializers. In that case, just redeclare in your @interface
's designated initializers. This is sufficient to document a designated initializer. Either that, or document an initializer or set of initializers as designated initializers, which would logically invalidate any superclass' designated initializers.
Of course, your initializer should call one of the superclass' designated initializers in its initialization.
Ex.1:
// implicitly adds a designated initializer. -init is still valid:
@interface MONObject : NSObject
- (instancetype)initWithString:(NSString *)pString;
@end
Ex.2:
// redefines the designated initializer. -init is not valid:
@interface MONObject : NSObject
// MONObject's designated initializer
- (instancetype)initWithString:(NSString *)pString;
@end
Ex.3:
// define all designated initializers:
@interface MONObject : NSObject
// MONObject's designated initializers:
- (instancetype)init;
- (instancetype)initWithString:(NSString *)pString;
@end
EDIT
Question clarified in comments.
When you are simply overriding an initializer declared by the superclass:
Is this true? Do we have to do this all the time?
Unless your class has initialization to perform, you do not need to explicitly override the superclass' designated initializer.
Your instance will be initialized to have zeroed memory.
Given:
@interface MONObject : NSObject
- (instancetype)initWithString:(NSString *)pString;
@property (nonatomic, copy, readwrite) NSString * string;
@end
@implementation MONObject
// if @property string should be initialized to nil, you may omit -[MONObject init]
// otherwise, initialize self here:
- (instancetype)init
{
// call super's designated initializer:
self = [super init];
// test it:
if (nil == self) return nil;
// init your state
_string = @"(null)";
return self;
}
- (instancetype)initWithString:(NSString *)pString;
{
// call super's designated initializer:
self = [super init]; // << will not call -[MONObject init]
// test it:
if (nil == self) return nil;
// init your state
_string = pString.copy;
return self;
}
@end