在 Objective-C 中有 designated 和 secondary 初始化方法的觀念翰苫。如果一個實例的初始化需要多個參數(shù)岖圈,那么使用所有參數(shù)進行初始化的方法可以作為 designated 初始化方法湃累。而使用一個或多個參數(shù)的初始化方法則作為 secondary 初始化方法,并且在對應(yīng)實現(xiàn)中調(diào)用前面的 designated 初始化方法。
在開發(fā)時捉超,可以使用NS_DESIGNATED_INITIALIZER
宏對 designated 初始化方法進行標(biāo)記服协,用來向調(diào)用者明確绍昂,無論其他哪個初始化方法都會通過調(diào)用這個方法來實現(xiàn)。對于不想讓調(diào)用者使用的初始化方法偿荷,可以使用 NS_UNAVAILABLE
宏來進行標(biāo)記禁用窘游。這樣一來,Xcode 的自動補全不會索引到該方法跳纳,如果強制調(diào)用忍饰,編譯器會報錯(但是通過 runtime 還是可以調(diào)用的)。
需要注意的是寺庄,若為子類指定了一個 NS_DESIGNATED_INITIALIZER 宏標(biāo)記的初始化方法艾蓝,那么在子類中必須重寫父類的 designated 初始化方法力崇,該方法的實現(xiàn)是調(diào)用子類自身的 designated 初始化方法。在子類自身的 designated 初始化方法的實現(xiàn)中赢织,又需要調(diào)用父類的 designated 初始化方法亮靴。這段話比較繞,下面用一個例子說明于置。
@interface AwesomeTips : NSObject
//該方法被禁用
- (instancetype)new NS_UNAVAILABLE;
//secondary初始化方法
- (instancetype)initWithName:(NSString *)aName;
//designated初始化方法
- (instancetype)initWithName:(NSString *)aName
wish:(NSString *)ourWish
NS_DESIGNATED_INITIALIZER;
@end
#import "AwesomeTips.h"
@interface AwesomeTips ()
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *wish;
@end
@implementation AwesomeTips
//父類NSObject的designated方法為init茧吊,這里必須重寫
//否則警告“Method override for the designated initializer of the superclass '-init' not found”
//在其重寫實現(xiàn)中,調(diào)用子類指定的designated方法俱两,并提供默認(rèn)參數(shù)
- (instancetype)init {
return [self initWithName:@"知識小集" wish:@"分享知識"];
}
//secondary初始化方法的實現(xiàn)饱狂,調(diào)用自身的designated方法
- (instancetype)initWithName:(NSString *)aName {
return [self initWithName:aName wish:@"分享知識"];
}
//自身的designated初始化方法
//需先調(diào)用父類的designated方法,而后使用參數(shù)賦值
- (instancetype)initWithName:(NSString *)aName wish:(NSString *)ourWish {
if (self = [super init]) {
self.name = aName;
self.wish = ourWish;
}
return self;
}
@end