採用NS_DESIGNATED_INITIALIZER
是很好在http://useyourloaf.com/blog/2014/08/19/xcode-6-objective-c-modernization.html解釋:
The designated initializer guarantees the object is fully initialised by sending an initialization message to the superclass. The implementation detail becomes important to a user of the class when they subclass it. The rules for designated initializers in detail:
- A designated initializer must call (via super) a designated initializer of the superclass. Where NSObject is the superclass this is just [super init].
- Any convenience initializer must call another initializer in the class - which eventually leads to a designated initializer.
- A class with designated initializers must implement all of the designated initializers of the superclass.
作爲一個例子,如果接口是
@interface MyClass : NSObject
@property(copy, nonatomic) NSString *name;
-(instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
-(instancetype)init;
@end
則編譯器檢查是否(便利)初始化init
調用 的(指定)初始化程序initWithName:
,所以這會引起警告:
-(instancetype)init
{
self = [super init];
return self;
}
,這將是確定:
-(instancetype)init
{
self = [self initWithName:@""];
return self;
}
在斯威夫特的有關規定確定的和方便的初始化是更嚴格, 如果你混的Objective-C和斯威夫特代碼,標誌着指定目標-C初始化器幫助編譯器執行規則。
例如,這斯威夫特子類會導致編譯器錯誤:
class SwClass: MyClass {
var foo : String
init(foo : String) {
self.foo = foo
super.init()
}
}
,這將是確定:
class SwClass: MyClass {
var foo : String
init(foo : String) {
self.foo = foo
super.init(name: "")
}
}
Objective-C中的概念並不是很好的想法,因爲'initWithName:@「」'在進行子類化時並不總是有意義的。相反,通常從超類中重寫的指定初始化器應該拋出異常,說使用來自子類的指定初始化器。 – Andy 2015-10-18 15:47:23
要添加到Martin的答案,您可能想要完全禁止用戶調用默認的初始化程序,在這種情況下,您可以使用以下內容: - (instancetype)init NS_UNAVAILABLE; – 2016-02-18 16:21:28