前言
我們都知道, 在oc中創(chuàng)建一個對象的實現(xiàn)是這樣的:
NSObject *obj = [[NSObject alloc] init];
即兩步創(chuàng)建, 從字面意思可以理解為: 分配內(nèi)存 和 初始化
那么這個alloc 和 init分別都做了什么事情呢?
正文
alloc
alloc負責(zé)創(chuàng)建對象, 這個過程包括了分配足夠的內(nèi)存來保存對象, 寫入isa指針, 初始化引用計數(shù), 以及重置所有實例變量這四個過程.
在OC的源碼頭文件中可以看到, alloc的定義如下:
+ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
即: alloc方法會返回一個未被初始化的對象實例.
我們知道OC中的消息機制是這樣的: 每一個方法都將轉(zhuǎn)化成一條 objc_msgSend()函數(shù).
換言之, 也就是說alloc方法提供了objc_msgSend()函數(shù)的發(fā)送目標(biāo).
init
init負責(zé)初始化對象, 這意味著此時此對象處于可用狀態(tài), 即對象的實例變量可以被賦予合理有效值.
在OC的頭文件中可以看到, init的定義如下:
- (instancetype)init;
這個沒什么要說的, 不過這個要提一下另一個問題:
我們在重寫一個對象的init方法的時候, 都是這樣的格式:
- (instancetype)init {
if (self = [super init]) {
//TODO...
}
return self;
}
我們都只要, 重寫的時候要調(diào)用 [super init], 那么到底為什么要這么寫呢 ?
這里有一個很重要的部分:
init方法可以通過返回nil來告訴開發(fā)者, 初始化失敗了
即, 如果你的超類初始化自己的時候失敗了, 那么當(dāng)前的類即處于一個不穩(wěn)定狀態(tài),
即有可能你的初始化成功, 也有可能失敗.
所以, 此時你的實現(xiàn)里不要再繼續(xù)你的初始化并且要通過返回nil
如果不這么做的話, 接下來的操作可能會操控一個不可用對象(即創(chuàng)建失敗),
這個行為是不可預(yù)測的, 有可能會導(dǎo)致程序崩潰.
所以我們在重寫init方法的時候, 要用以上的寫法, 保證你的創(chuàng)建過程的容錯性.`
結(jié)尾
謝謝.