級別: ★☆☆☆☆
標籤:「NS_DESIGNATED_INITIALIZER 」「NS_UNAVAILABLE」「iOS指定初始化方法」
作者: WYW
審校: QiShare團隊
前言:筆者最近了解了部分SDK開發相關的內容,在涉及指定檢視控制器(下文用VC代指檢視控制器)的初始化方法的時候,遇到了一些問題。這裡筆者給大家分享下設定方法,如有不同見解,敬請指教。
筆者遇到的問題如下:
筆者希望 使用SDK的業務能夠使用 SDK中確定的初始化VC的方法; 下邊筆者以需要傳入VC的導航欄標題並初始化相應VC為例,來闡明相關問題。 對於上述情況,有多種處理方式,如:
- 在SDK暴露的標頭檔案中,文字說明,用哪個初始化方法;在文件中說明, 用哪個初始化方法;在提供的Demo中,寫明相應地示例程式碼。
- 利用系統給的巨集NS_DESIGNATED_INITIALIZER指定vc初始化方法 指定初始化方法部分,可以使用巨集NS_DESIGNATED_INITIALIZER指定,那麼如果業務沒有看SDK標頭檔案,直接使用new 或者 alloc init的方式指定初始化方法,那麼我們初始化VC所需的導航欄標題就不能得以正常傳入。
對於這種情況,我們可以提供如下3種方法:
- 把不想業務使用的初始化方法,使用系統巨集 NS_UNAVAILABLE 把相應初始化方法設定為不可用;如禁用new ,這樣的效果是:業務如果想使用new 初始化VC,會發現有錯誤提示,使用這種方法比較簡單。
- 對於不想業務使用的初始化方法,在實現檔案中,實現相應的方法,並且給予預設值。比如說對於初始化VC的導航欄標題的情況,給定預設標題為defaultNavigationTitle。不過這種初始化方法,不適用傳入重要引數的情況,不然業務會覺得怪怪的。另外這種方式,以後如果有相關改動,可能改動程式碼會較多。
- 對於不想業務使用的初始化方法,在實現檔案中,實現相應的方法,並且丟擲崩潰,並且指定崩潰原因,在崩潰原因中說明應該使用的初始化VC的方法。對於這種方式,如果以後有改動,可能改動程式碼會較多。 相比如上三種處理方式,筆者更傾向於使用第一種,如果你有其他見解,歡迎討論。
下邊我們仍以初始化VC時,指定傳入導航欄標題為例,貼上相關的示例程式碼。
第一種方式:
// .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 導航欄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 導航欄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:進行初始化";
/*! @brief 導航欄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:
參考學習網址
-
Effective Objective-C 2.0:編寫高質量iOS與OS X程式碼的52個有效方法
小編微信:可加並拉入《QiShare技術交流群》。
關注我們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號)
推薦文章:
UIView中的hitTest方法
iOS關於tabBar的幾處筆記
A的女兒是B的女兒的媽媽,A是B的誰?
演算法小專欄:選擇排序
iOS Runloop(一)
iOS 常用除錯方法:LLDB命令
iOS 常用除錯方法:斷點
iOS 常用除錯方法:靜態分析
奇舞週刊