self = [super init]

初始化方法的標準結構是這樣子的:

- (instancetype)init
{
    self = [super init]; // call the designated initializer
    if (self) {
        // Custom initialization
    }
    return self;
}

我們主要來看看,這一句:

    self = [super init]; // call the designated initializer

問題1:[super init] 到底做了什么?

問題2:為什么把[super init]的值賦值給self?

問題3:我們用過了 alloc init的兩部創建,為什么不是[[super alloc] init]

先來回答問題3,因為這個問題是來搞笑的:

我們看下alloc方法是怎么定義的 
+ (instancetype)alloc;
可以看到alloc是一個類方法,而super不是一個類.

然后我們在來看看問題1:

[super init] 的結果可能有三種:
第一種:  [super init] 初始化成功,這個是最最正常的情況。
第二種:    [super init] 初始化失敗,我們都知道oc的兩步創建,alloc開辟內存空間,init初始化對象,但是init還有另外一個作用,在初始化失敗的時候,init方法會返回一個nil。回頭行文的最上面,如果self為nil,那么if(self)語句的內容,將不被執行,已確保程序健壯安全。
- (instancetype)init
{
    self = [super init]; // call the designated initializer
    if (self) {
        // Custom initialization
    }
    return self;
}
第三種:self = [super init]執行之后,內存指向了不相關的地址。這種情況的出現,一般是一下幾種情況:單例、類簇、對象為NSNumber類型、父類在初始化的時候釋放了當前對象,然后重新開辟了新的內存地址。   

最后,我們來使用《禪與 Objective-C 編程藝術》的原話來回答問題2:

如果你的超類沒有成功初始化它自己,你必須假設你在一個矛盾的狀態,并且在你的實現中不要處理你自己的初始化邏輯,同時返回 nil。如果你不是這樣做,你看你會得到一個不能用的對象,并且它的行為是不可預測的,最終可能會導致你的 app 發生 crash。

一句話概括:

if( self = [super init] )這是一種通常的建議寫法,賦值并測試nil只是為了防止超類在初始化過程中發生改變,返回了不同的對象。

參考:

《禪與 Objective-C 編程藝術》中文版
中文版地址:https://github.com/oa414/objc-zen-book-cn#class-cluster
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容