Skip to content

Instantly share code, notes, and snippets.

@swillits
Last active May 23, 2017 17:31
Show Gist options
  • Save swillits/3133e114f770947b3cf6 to your computer and use it in GitHub Desktop.
Save swillits/3133e114f770947b3cf6 to your computer and use it in GitHub Desktop.
// Subclass -> Superclass -> NSObject
//
// NSObject's designated initializer is -init
// Superclass's designated initializer is -initWithSomething:
// Subclass's designated initializer is -initWithSomethingElse:
//
// Superclass cannot be initialized with -init
// Subclass cannot be initialized with -init
// Subclass cannot be initialized with -initWithSomething:
//
// How do we correctly use NS_DESIGNATED_INITIALIZER and NS_UNAVAILABLE?
//
// ------------------------------------------------------------
// First pass:
// ------------------------------------------------------------
@interface NSObject
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
@interface Superclass : NSObject
- (instancetype)initWithSomething:(id)x;
@end
@interface Subclass : Superclass
- (instancetype)initWithSomethingElse:(id)x;
@end
@implementation Superclass
- (instancetype)initWithSomething:(id)x
{
return (self = [super init]);
}
@end
@implementation Subclass
- (instancetype)initWithSomethingElse:(id)x
{
return (self = [super initWithSomething:x]);
}
@end
// ------------------------------------------------------------
// Adding designated to our headers:
// ------------------------------------------------------------
@interface Superclass : NSObject
- (instancetype)initWithSomething:(id)x NS_DESIGNATED_INITIALIZER;
@end
@interface Subclass : Superclass
- (instancetype)initWithSomethingElse:(id)x NS_DESIGNATED_INITIALIZER;
@end
@implementation Superclass
// WARNING: Method override for the designated initializer of the superclass '-init' not found
- (instancetype)initWithSomething:(id)x
{
return (self = [super init]);
}
@end
@implementation Subclass
// WARNING: Method override for the designated initializer of the superclass '-initWithSomething:' not found
- (instancetype)initWithSomethingElse:(id)x
{
return (self = [super initWithSomething:x]);
}
@end
// ------------------------------------------------------------
// Adding unavailable to our headers:
// ------------------------------------------------------------
@interface Superclass : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithSomething:(id)x NS_DESIGNATED_INITIALIZER;
@end
@interface Subclass : Superclass
- (instancetype)initWithSomething:(id)x NS_UNAVAILABLE;
- (instancetype)initWithSomethingElse:(id)x NS_DESIGNATED_INITIALIZER;
@end
@implementation Superclass
// WARNING: Method override for the designated initializer of the superclass '-init' not found
- (instancetype)initWithSomething:(id)x
{
return (self = [super init]);
}
@end
@implementation Subclass
// WARNING: Method override for the designated initializer of the superclass '-initWithSomething:' not found
- (instancetype)initWithSomethingElse:(id)x
{
return (self = [super initWithSomething:x]);
}
@end
// ------------------------------------------------------------
// Adding overrides to our implementations:
// ------------------------------------------------------------
@interface Superclass : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithSomething:(id)x NS_DESIGNATED_INITIALIZER;
@end
@interface Subclass : Superclass
- (instancetype)initWithSomething:(id)x NS_UNAVAILABLE;
- (instancetype)initWithSomethingElse:(id)x NS_DESIGNATED_INITIALIZER;
@end
@implementation Superclass
- (instancetype)init
{
assert(false);
return nil;
}
- (instancetype)initWithSomething:(id)x
{
return (self = [super init]);
}
@end
@implementation Subclass
- (instancetype)initWithSomething:(id)x
{
assert(false);
return nil;
}
- (instancetype)initWithSomethingElse:(id)x
{
return (self = [super initWithSomething:x]);
}
@end
//
// ------------------------------------------------------------
// Conclusion:
// ------------------------------------------------------------
//
// Correct usage:
//
// - If a subclass does not support being initialized via a
// superclass's designated initializer then:
//
// 1) Mark it as uninitialized in the subclass's header
// 2) Override it in the subclass's implementation to simply return nil.
//
// The purpose of requiring the override is not clear to me.
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment