級別: ★☆☆☆☆
標籤:「NS_DESIGNATED_INITIALIZER 」「NS_UNAVAILABLE」「iOS指定初始化方法」
做者: WYW
審校: QiShare團隊php
前言:筆者最近了解了部分SDK開發相關的內容,在涉及指定視圖控制器(下文用VC代指視圖控制器)的初始化方法的時候,遇到了一些問題。這裏筆者給你們分享下設置方法,若有不一樣看法,敬請指教。git
筆者遇到的問題以下:github
筆者但願 使用SDK的業務可以使用 SDK中肯定的初始化VC的方法; 下邊筆者以須要傳入VC的導航欄標題並初始化相應VC爲例,來闡明相關問題。 對於上述狀況,有多種處理方式,如:算法
- 在SDK暴露的頭文件中,文字說明,用哪一個初始化方法;在文檔中說明, 用哪一個初始化方法;在提供的Demo中,寫明相應地示例代碼。
- 利用系統給的宏NS_DESIGNATED_INITIALIZER指定vc初始化方法 指定初始化方法部分,可使用宏NS_DESIGNATED_INITIALIZER指定,那麼若是業務沒有看SDK頭文件,直接使用new 或者 alloc init的方式指定初始化方法,那麼咱們初始化VC所需的導航欄標題就不能得以正常傳入。
對於這種狀況,咱們能夠提供以下3種方法:bash
- 把不想業務使用的初始化方法,使用系統宏 NS_UNAVAILABLE 把相應初始化方法設置爲不可用;如禁用new ,這樣的效果是:業務若是想使用new 初始化VC,會發現有錯誤提示,使用這種方法比較簡單。
- 對於不想業務使用的初始化方法,在實現文件中,實現相應的方法,而且給予默認值。好比說對於初始化VC的導航欄標題的狀況,給定默認標題爲defaultNavigationTitle。不過這種初始化方法,不適用傳入重要參數的狀況,否則業務會以爲怪怪的。另外這種方式,之後若是有相關改動,可能改動代碼會較多。
- 對於不想業務使用的初始化方法,在實現文件中,實現相應的方法,而且拋出崩潰,而且指定崩潰緣由,在崩潰緣由中說明應該使用的初始化VC的方法。對於這種方式,若是之後有改動,可能改動代碼會較多。 相好比上三種處理方式,筆者更傾向於使用第一種,若是你有其餘看法,歡迎討論。
下邊咱們仍以初始化VC時,指定傳入導航欄標題爲例,貼上相關的示例代碼。微信
第一種方式:ide
// .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];
}
複製代碼
第二種方式:oop
.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:QiDesignatedInitializerui
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 經常使用調試方法:靜態分析
奇舞週刊