OC對象(一)-- alloc和init底層到底在干嘛

OC對象(一)-- alloc和init底層到底在干嘛
OC對象(二)-- 內(nèi)存對齊和calloc中的16字節(jié)對齊
OC對象(三)-- isa結(jié)構(gòu)分析


本文使用的源碼是objc4-787.1

init


看看init源碼:

- (id)init {
    return _objc_rootInit(self);
}

id _objc_rootInit(id obj)
{
    // In practice, it will be hard to rely on this function.
    // Many classes do not properly chain -init calls.
    return obj;
}

init方法中調(diào)用了_objc_rootInit方法淌实,最后返回的就是self粮彤。所以可以說init中什么都沒有做肝劲。

用個demo驗證一下:

DZObject *obj1 = [DZObject alloc];
DZObject *p1 = [obj1 init];
DZObject *p2 = [obj1 init];
    
NSLog(@"%@ - %@ - %@", obj1, p1, p2);
NSLog(@"%p - %p - %p", obj1, p1, p2);
NSLog(@"%p - %p - %p", &obj1, &p1, &p2);

說明:

  1. DZObject是自定義的類愤炸,繼承自NSObject。
  2. alloc一個實例obj1
  3. 再分別定義實例p1和p2战惊,通過obj1調(diào)用init方法
  4. 分別打印實例對象溯职、指針、和指針地址

打印結(jié)果如圖:



對象和指針都是相同的胳施,指針地址不同。內(nèi)存中結(jié)構(gòu)如圖:


init方法是蘋果提供的工廠方法肢专,對實例對象沒有進行任何處理巾乳。開發(fā)者可以自定義init的實現(xiàn),比如初始化一些屬性數(shù)據(jù)的工作鸟召。

alloc


alloc流程圖


圖中粉色部分是alloc的核心部分,主要進行了三部操作

  1. cls->instanceSize:計算需要開辟的內(nèi)存空間氨鹏,內(nèi)部實現(xiàn)是個算法欧募,在最新源碼的算法是16字節(jié)對齊。
  2. calloc:用計算好的size作為參數(shù)仆抵,調(diào)用calloc方法跟继,開辟內(nèi)存空間。
  3. obj->initInstanceIsa:初始化示例的isa
instanceSize實現(xiàn)(字節(jié)對齊算法)

函數(shù)方法調(diào)用流程圖入下:


核心代碼如下:

static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

計算過程示例:例如x=4镣丑,如下表:

16進制 2進制
x=4 0000 0100
+
15 0000 1111
=
19 0001 0011
&
~15 1111 0000
16 0001 0000

經(jīng)過算法后舔糖,得到的結(jié)果都是16的倍數(shù)(可以使用大于16的數(shù)字算一遍)。這就是16字節(jié)對齊莺匠。

new


經(jīng)常會用new方法直接示例對象金吗,例如

DZObject *obj = [DZObject new];

看看new的底層源碼實現(xiàn):

+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}

通過源碼可以看到,new做了alloc和init合并的事趣竣。==但是不建議直接使用new摇庙。如果一個自定義類中添加了initWithXXX:方法,方法中做了初始化的相關(guān)邏輯遥缕。那么直接調(diào)用new卫袒,只是調(diào)用了系統(tǒng)提供的init方法。==

NSObject alloc


當用NSObject alloc的時候单匣,走的流程與上面的一樣夕凝。其實alloc的真正調(diào)用的是objc_alloc方法,驗證方式:在alloc下斷點户秤,打開匯編码秉,運行:


可以看到匯編代碼調(diào)用的是objc_alloc,接下來看看它的源碼實現(xiàn):

// Calls [cls alloc].
id
objc_alloc(Class cls)
{
    return callAlloc(cls, true/*checkNil*/, false/*allocWithZone*/);
}

因此alloc的真正的流程圖是這樣的:


擴展 - 那為什么調(diào)用alloc方法時會先調(diào)用objc_alloc函數(shù)呢虎忌?


蘋果使用LLVM編譯工具泡徙,在編譯期間對alloc方法進行了特殊處理,可以理解為是系統(tǒng)級別的hook方法膜蠢,也就是將alloc方法和objc_alloc函數(shù)進行交換堪藐。
展示一下部分llvm源碼中tryGenerateSpecializedMessageSend函數(shù)中的部分實現(xiàn):

再來看看tryGenerateSpecializedMessageSend的調(diào)用地方:

大致的思路是莉兰,系統(tǒng)將alloc標記為特殊消息發(fā)送。一個類調(diào)用alloc的時候系統(tǒng)會去調(diào)用objc_alloc礁竞。在objc_alloc源碼中通過objc_msgSend再次發(fā)送一次alloc消息(這次不會被系統(tǒng)標記成特殊消息糖荒,正常調(diào)用alloc方法)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末模捂,一起剝皮案震驚了整個濱河市捶朵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狂男,老刑警劉巖综看,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異岖食,居然都是意外死亡红碑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門泡垃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來析珊,“玉大人,你說我怎么就攤上這事蔑穴≈已埃” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵存和,是天一觀的道長奕剃。 經(jīng)常有香客問我,道長捐腿,這世上最難降的妖魔是什么祭饭? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮叙量,結(jié)果婚禮上倡蝙,老公的妹妹穿的比我還像新娘。我一直安慰自己绞佩,他們只是感情好寺鸥,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著品山,像睡著了一般胆建。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肘交,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天笆载,我揣著相機與錄音,去河邊找鬼。 笑死凉驻,一個胖子當著我的面吹牛腻要,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涝登,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼雄家,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胀滚?” 一聲冷哼從身側(cè)響起趟济,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咽笼,沒想到半個月后顷编,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡剑刑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年勾效,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叛甫。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杨伙,靈堂內(nèi)的尸體忽然破棺而出其监,到底是詐尸還是另有隱情,我是刑警寧澤限匣,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布抖苦,位于F島的核電站,受9級特大地震影響米死,放射性物質(zhì)發(fā)生泄漏锌历。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一峦筒、第九天 我趴在偏房一處隱蔽的房頂上張望究西。 院中可真熱鬧,春花似錦物喷、人聲如沸卤材。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扇丛。三九已至,卻和暖如春尉辑,著一層夾襖步出監(jiān)牢的瞬間帆精,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卓练,地道東北人隘蝎。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像昆庇,于是被迫代替她去往敵國和親末贾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348