級別: ★☆☆☆☆
標(biāo)簽:「NS_DESIGNATED_INITIALIZER 」「NS_UNAVAILABLE」「iOS指定初始化方法」
作者: WYW
審校: QiShare團(tuán)隊
前言:筆者最近了解了部分SDK開發(fā)相關(guān)的內(nèi)容校赤,在涉及指定視圖控制器(下文用VC代指視圖控制器)的初始化方法的時候,遇到了一些問題筒溃。這里筆者給大家分享下設(shè)置方法马篮,如有不同見解,敬請指教怜奖。
筆者遇到的問題如下:
筆者希望 使用SDK的業(yè)務(wù)能夠使用 SDK中確定的初始化VC的方法浑测;
下邊筆者以需要傳入VC的導(dǎo)航欄標(biāo)題并初始化相應(yīng)VC為例,來闡明相關(guān)問題歪玲。
對于上述情況迁央,有多種處理方式,如:
- 在SDK暴露的頭文件中滥崩,文字說明岖圈,用哪個初始化方法;在文檔中說明钙皮, 用哪個初始化方法蜂科;在提供的Demo中,寫明相應(yīng)地示例代碼短条。
- 利用系統(tǒng)給的宏NS_DESIGNATED_INITIALIZER指定vc初始化方法
指定初始化方法部分导匣,可以使用宏NS_DESIGNATED_INITIALIZER指定,那么如果業(yè)務(wù)沒有看SDK頭文件茸时,直接使用new 或者 alloc init的方式指定初始化方法贡定,那么我們初始化VC所需的導(dǎo)航欄標(biāo)題就不能得以正常傳入。
對于這種情況可都,我們可以提供如下3種方法:
- 把不想業(yè)務(wù)使用的初始化方法缓待,使用系統(tǒng)宏 NS_UNAVAILABLE 把相應(yīng)初始化方法設(shè)置為不可用;如禁用new 汹粤,這樣的效果是:業(yè)務(wù)如果想使用new 初始化VC命斧,會發(fā)現(xiàn)有錯誤提示田晚,使用這種方法比較簡單嘱兼。
- 對于不想業(yè)務(wù)使用的初始化方法,在實現(xiàn)文件中贤徒,實現(xiàn)相應(yīng)的方法芹壕,并且給予默認(rèn)值汇四。比如說對于初始化VC的導(dǎo)航欄標(biāo)題的情況,給定默認(rèn)標(biāo)題為defaultNavigationTitle踢涌。不過這種初始化方法通孽,不適用傳入重要參數(shù)的情況,不然業(yè)務(wù)會覺得怪怪的睁壁。另外這種方式背苦,以后如果有相關(guān)改動,可能改動代碼會較多潘明。
- 對于不想業(yè)務(wù)使用的初始化方法行剂,在實現(xiàn)文件中,實現(xiàn)相應(yīng)的方法钳降,并且拋出崩潰厚宰,并且指定崩潰原因,在崩潰原因中說明應(yīng)該使用的初始化VC的方法遂填。對于這種方式铲觉,如果以后有改動,可能改動代碼會較多吓坚。
相比如上三種處理方式撵幽,筆者更傾向于使用第一種,如果你有其他見解礁击,歡迎討論并齐。
下邊我們?nèi)砸猿跏蓟疺C時,指定傳入導(dǎo)航欄標(biāo)題為例客税,貼上相關(guān)的示例代碼况褪。
第一種方式:
// .h 文件
- (instancetype)initWithSomething:(id)someThing NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
// .m 文件
/*! @brief 導(dǎo)航欄title */
@property (nonatomic, copy) NSString *navTitle;
- (instancetype)initWithSomething:(id)someThing {
// Cannot assign to 'self' outside of a method in the init family
// 指定初始化方法需要以 1. init開頭 2. 并且init后邊緊挨著地字母是大寫的
self = [super initWithNibName:nil bundle:nil];
if (!self) {
return nil;
}
_navTitle = someThing;
[self commonInit];
return self;
}
- (void)commonInit {
self.navigationItem.title = _navTitle;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
}
第二種方式:
.h
- (instancetype)initWithSomething:(id)someThing;
// .m 文件
/*! @brief 導(dǎo)航欄title */
@property (nonatomic, copy) NSString *navTitle;
- (instancetype)initWithSomething:(id)someThing {
self = [super init];
if (!self) {
return nil;
}
_navTitle = someThing;
return self;
}
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
[self commonInit];
return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (!self) {
return nil;
}
[self commonInit];
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (!self) {
return nil;
}
[self commonInit];
return self;
}
- (void)commonInit {
_navTitle = @"Default";
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = _navTitle;
self.view.backgroundColor = [UIColor whiteColor];
}
第三種方式:
// .h 文件
- (instancetype)initWithSomething:(id)someThing;
// .m 文件
static NSString *const kExceptionName = @"初始化方法有誤";
static NSString *const kExceptionReason = @"請使用initWithSomething:進(jìn)行初始化";
/*! @brief 導(dǎo)航欄title */
@property (nonatomic, copy) NSString *navTitle;
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = _navTitle;
self.view.backgroundColor = [UIColor whiteColor];
}
+ (instancetype)new {
@throw [[self class] initExceptioin];
return nil;
}
- (instancetype)init {
@throw [[self class] initExceptioin];
return nil;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
@throw [[self class] initExceptioin];
return nil;
}
- (instancetype)initWithSomething:(id)someThing {
self = [super init];
if (!self) {
return nil;
}
_navTitle = someThing;
return self;
}
+ (NSException *)initExceptioin {
return [NSException exceptionWithName:kExceptionName reason:kExceptionReason userInfo:nil];
}
Demo:
參考學(xué)習(xí)網(wǎng)址
Effective Objective-C 2.0:編寫高質(zhì)量iOS與OS X代碼的52個有效方法
推薦文章:
UIView中的hitTest方法
iOS關(guān)于tabBar的幾處筆記
A的女兒是B的女兒的媽媽,A是B的誰更耻?
算法小專欄:選擇排序
iOS Runloop(一)
iOS 常用調(diào)試方法:LLDB命令
iOS 常用調(diào)試方法:斷點
iOS 常用調(diào)試方法:靜態(tài)分析