起始
不知道源碼如盲人摸象,只能靠猜,最近才知道OC的一些代碼是開源的,有很多值得待發(fā)掘的東西。
objc源碼地址, 或者使用有人做的可編譯版??梢圆榭丛创a,還可以修改調(diào)試,非常好!
本文用的是objc4-706
+load方法

看完代碼之后有幾個(gè)點(diǎn)值得注意:
加載的邏輯是:先把具有+load方法的類方法一個(gè)數(shù)組(loadable_classes)里,然后在一起調(diào)用它們+load方法,所以在這個(gè)數(shù)組里的順序決定了+load方法的順序。如果類本身(不包括category和父類)沒(méi)有實(shí)現(xiàn)
+load方法,就不會(huì)加入這個(gè)數(shù)組。schedule_class_load函數(shù)內(nèi)部會(huì)先調(diào)用父類的schedule_class_load,這導(dǎo)致父類處在loadable_classes里的前面,它+load函數(shù)先調(diào)用。在外界看來(lái)好像是子類的+load內(nèi)部調(diào)用了[super load]。其實(shí)每個(gè)類的+load是互相獨(dú)立的。category的
+load和類本身的+load也是獨(dú)立的,也就是你定義了10個(gè)category,每個(gè)都定義了自己的+load方法,那么都會(huì)調(diào)用。在
+load方法調(diào)用之前,類本身的方法是加載好了的。至于定義在category里的方法和父類的方法,在我用的這個(gè)版本(objc4-706)這些也已經(jīng)完成。+load方法只是系統(tǒng)加載過(guò)程給外界提供的一個(gè)時(shí)機(jī)而已,不存在默認(rèn)實(shí)現(xiàn),是個(gè)空殼方法。如果不實(shí)現(xiàn)自己的代碼,那么調(diào)用[xxx load]沒(méi)有實(shí)際意義。
+initialize方法

-
+initialize的流程簡(jiǎn)單很多,它是靠對(duì)這個(gè)類的使用觸發(fā)的,任何一個(gè)方法。因?yàn)閷?duì)象構(gòu)建要使用+alloc,那么第一次可以肯定就是類方法了。 -
cla->isInitialized()是判斷標(biāo)識(shí),進(jìn)入這兒判斷函數(shù)內(nèi)看:getMeta()->info & CLS_INITIALIZED,通過(guò)在類結(jié)構(gòu)體的內(nèi)存里設(shè)置標(biāo)識(shí)為來(lái)存儲(chǔ)的,CLS_INITIALIZED就是是否初始化的標(biāo)識(shí)。 - 值得注意的是
+initialize的觸發(fā)方式,+load是直接使用它的IMP(函數(shù)指針)來(lái)調(diào)用的,而這里是objc_msgSend,這樣就會(huì)追溯到父類或者轉(zhuǎn)發(fā)方法。在外界看來(lái),就會(huì)出現(xiàn)這樣的現(xiàn)象:子類在第一次使用的時(shí)候,如果子類自己沒(méi)實(shí)現(xiàn)+initialize,會(huì)觸發(fā)父類的+initialize,有N個(gè)子類就會(huì)觸發(fā)N次,而+load方法卻不會(huì),當(dāng)前類沒(méi)實(shí)現(xiàn),就不會(huì)有任何函數(shù)觸發(fā)。+initialize的行為模式跟普通的方法調(diào)用是一樣的。
類的方法列表、屬性、協(xié)議的加載
因?yàn)閏ategory的存在,類實(shí)際的列表、屬性、協(xié)議是需要整合的,甚至可能category定義在另一個(gè)靜態(tài)庫(kù)里。
方法列表和屬性、協(xié)議列表幾乎是一起處理的,加載的邏輯是是一樣的,所以就只做了方法列表的圖。

- 核心是
rw->methods.attachLists函數(shù),先通過(guò)這個(gè)函數(shù)把類本身的方法列表添加到methods成員里。然后把所有category的方法列表加進(jìn)來(lái)。 - 關(guān)注方法列表的問(wèn)題是因?yàn)殛P(guān)于iOS底層原理的若干解析這個(gè)里面的第6題。發(fā)現(xiàn)現(xiàn)在這個(gè)版本的objc代碼和之前的不一樣,但是有個(gè)邏輯是一樣的:
- 都是把category的方法放在了方法列表的前面,也就是類本身方法會(huì)被category的同方法覆蓋
- 類本身的方法占一個(gè)方法列表,每個(gè)category的方法占一個(gè)方法列表,所以整合后的類的方法列表實(shí)際是方法列表的列表
- 這兩條對(duì)屬性(properties)和協(xié)議(protocols)也使用。