先拋出一個小問題,然后延伸引入接下來要說的
zuyuClass *z = [zuyuClass alloc];
zuyuClass *z1 = [z init];
zuyuClass *z2 = [z init];
NSLog(@"%p - %p - %p",z,z1,z2);
思考一下是控制臺的輸出是怎么樣的
思考過后代碼試一下
z,z1,z2三個對象的地址是完全一樣的
alloc 做了些什么?init 做了些什么?
OK我們現(xiàn)在正是開始今天的內(nèi)容
想知道 alloc 都干了些什么.最簡單的方式就是看源碼對吧.來,咱們瞄一眼源碼去
繼續(xù)往下
繼續(xù)
好,到這里簡單說一下,會走到紅色選中的位置,為什么會走到這兒呢? 通過下符號斷點,顯示的匯編中看出來,這咱們就簡單的一句帶過,不詳細說.
咱們繼續(xù)往下
class_createInstance
繼續(xù)往下
好了 劃重點了開始
重點1. ?? ? size_t size = cls->instanceSize(extraBytes); ? ? 6518行
創(chuàng)建對象首先最重要的大家應該都知道啦 ?, ?內(nèi)存 , 對吧. 這個 size 就是獲取該對象需要多大的空間,從而進行字節(jié)對齊
(字節(jié)對齊簡單來說就是 ,比如改對象需要12個字節(jié), 那么就返回16字節(jié) .如果該對象需要23個字節(jié),那么就返回24字節(jié) . 為什么要對齊? ?玩過逆向,匯編或者研究過底層的朋友就比較理解這個,在這咱們就不多說了)
這是 alloc 做的第一件事 .計算并進行字節(jié)對齊.
咱們繼續(xù)拋出一個問題,比如現(xiàn)在有個 zuyuClass 的類. ?有NSString 類型的 name(8字節(jié)) 和 int 類型的 age(4字節(jié)) .根據(jù)字節(jié)對齊. 這個類的對象占用了多少字節(jié)的內(nèi)存?
腦袋里邊想著是16的,可以用代碼輸出一下 看一下 , 是24 .問題又來了 ,為什么是24個字節(jié)
重點2.? ? ? ? obj->initInstanceIsa(cls, hasCxxDtor) ? 6525行.
創(chuàng)建一個 isa. ?isa 占用了8個字節(jié) . 萬物皆對象,對象皆有 isa
ok.這個時候大家是不是就以為zuyuClass在內(nèi)存中就占用24個字節(jié)了?
NO,NONONO .重點3來了 ?------>?obj = (id)calloc(1, size); ? 6523行
這個 calloc 最終會走到這里(下圖)
所以最終 zuyuClass 的這個對象內(nèi)存中占用的空間是32字節(jié)而不是24字節(jié)
alloc我們就說到這里
接下來簡單說說 init. 為什么要簡單說說呢,因為沒辦法詳細說啊
來,我們看一眼源碼
看到了吧 .init 干嘛了?init 啥都沒干!只是返回了自己!
所以也就解釋了一開始拋出的問題 ?.是不是看到這里已經(jīng)顛覆了你的 alloc 是開辟空間,init 是初始化的理解?
可能有同學要問一下,init 既然啥都沒干,為啥還要 init 這個方法,要它何用?
一句話回答, 自定義初始化. 也就是重寫 init. ?
那么現(xiàn)在最后拋出一個問題
在創(chuàng)建某一個類的對象的時候,alloc 和 init 分別起到了什么作用. 是不是瞬間感覺腦海里的回答比之前高大上了許多?