1. 調(diào)用順序
以main為分界,load方法在main函數(shù)之前執(zhí)行,initialize在main函數(shù)之后執(zhí)行
2.相同點(diǎn)和不同點(diǎn)
2.1 相同點(diǎn)
- load和initialize會(huì)被自動(dòng)調(diào)用,不能手動(dòng)調(diào)用它們。
- 子類實(shí)現(xiàn)了load和initialize的話,會(huì)隱式調(diào)用父類的load和initialize方法
- load和initialize方法內(nèi)部使用了鎖,因此它們是線程安全的。
2.2 不同點(diǎn)
- 子類中沒(méi)有實(shí)現(xiàn)load方法的話,不會(huì)調(diào)用父類的load方法;而子類如果沒(méi)有實(shí)現(xiàn)initialize方法的話,也會(huì)自動(dòng)調(diào)用父類的initialize方法。
- load方法是在類被裝在進(jìn)來(lái)的時(shí)候就會(huì)調(diào)用,initialize在第一次給某個(gè)類發(fā)送消息時(shí)調(diào)用(比如實(shí)例化一個(gè)對(duì)象),并且只會(huì)調(diào)用一次,是懶加載模式,如果這個(gè)類一直沒(méi)有使用,就不回調(diào)用到initialize方法。
3. load
在執(zhí)行l(wèi)oad方法之前,會(huì)調(diào)用load_images方法,用來(lái)掃描鏡像中的+ load符號(hào),將需要調(diào)用 load 方法的類添加到一個(gè)列表中loadable_classes,在這個(gè)列表中,會(huì)先把父類加入到待加載列表,這樣保證父類在父類在子類錢調(diào)用load方法,而分類中的load方法會(huì)在類的load的方法后面加入另外一個(gè)待加載列表loadable_categories,這樣保證了兩個(gè)規(guī)則:
- 父類先于子類調(diào)用
- 類先于分類調(diào)用
在掃描完load方法加入到待加載方法后,會(huì)調(diào)用call_load_methods,先從loadable_classes調(diào)用類的load方法,call_class_loads;調(diào)用完loadable_classes后會(huì)調(diào)用loadable_categories中分類的load方法,call_category_loads。
調(diào)用順序如下:
- 父類load先于類添加到loadable_classes列表,通過(guò)call_class_loads,調(diào)用列表中的load方法,這樣父類的load先于類的load執(zhí)行
- 當(dāng)loadable_classes為空的時(shí)候,查看loadable_classes是否為空,如果不為空則調(diào)用call_category_loads加載分類中的load方法,這樣分類的load在類之后執(zhí)行
4. initialize
initialize 只會(huì)在對(duì)應(yīng)類的方法第一次被調(diào)用時(shí),才會(huì)調(diào)用,initialize 方法是在 alloc 方法之前調(diào)用的,alloc 的調(diào)用導(dǎo)致了前者的執(zhí)行。
initialize的調(diào)用棧中,直接調(diào)用其方法的其實(shí)是_class_initialize 這個(gè)C語(yǔ)言函數(shù),在這個(gè)方法中,主要是向?yàn)槌跏蓟念惏l(fā)送+initialize消息,不過(guò)會(huì)強(qiáng)制父類先發(fā)送。
與 load 不同,initialize 方法調(diào)用時(shí),所有的類都已經(jīng)加載到了內(nèi)存中。
5. 使用場(chǎng)景
5.1 load
load一般是用來(lái)交換方法Method Swizzle,由于它是線程安全的,而且一定會(huì)調(diào)用且只會(huì)調(diào)用一次,通常在使用UrlRouter的時(shí)候注冊(cè)類的時(shí)候也在load方法中注冊(cè)
5.2 initialize
initialize方法主要用來(lái)對(duì)一些不方便在編譯期初始化的對(duì)象進(jìn)行賦值,或者說(shuō)對(duì)一些靜態(tài)常量進(jìn)行初始化操作