load
調(diào)用時(shí)機(jī):app啟動(dòng)時(shí) 動(dòng)態(tài)庫加載的時(shí)候(在main函數(shù)之前調(diào)用)
調(diào)用順序:父類->父類 -> 本類 -> 分類
- 其中沒有實(shí)現(xiàn)
+load方法的類就跳過
- 如:入父類a->父類b->本類->分類(其中
b繼承a且b沒有實(shí)現(xiàn)+load則調(diào)用:父類a->本類->分類)
- 全部分類都會(huì)調(diào)用,其調(diào)用順序由
Compile Source順序決定
具體剖析: 直接調(diào)用IMP 函數(shù)指針
類加載的時(shí)候,先調(diào)用
objc_init(void)每當(dāng)有新的 library 被 map 到
runtime時(shí),調(diào)用load_images方法。-
load_images-
perpar_load_methods()主類的父類和自身添加到全局靜態(tài)結(jié)構(gòu)體 loadable_list 中之后,添加主類的分類,將分類添加到全局靜態(tài)結(jié)構(gòu)體loadable_categories中。所以子類優(yōu)先分類。- 上了線程安全:遞歸鎖 (
recursive_mutex_t)
- 添加本類(本類中的
include的類 且沒有執(zhí)行過+load)及父類。。。父類到loadable_List中。
(遞歸調(diào)用schedule_class_load-> 父類。。。添加到loadable_List) - 添加
category到loadabel_categorys中
- 上了線程安全:遞歸鎖 (
-
call_load_methods();當(dāng)library加載完成后,需要調(diào)用call_load_methods- 用
objc_autoReleasePoolPush創(chuàng)建一個(gè)pool。
-
do while循環(huán)調(diào)用父類->本類->分類 的+load方法。(loadable_classes_used->為一個(gè)全局的指針偏移變量并在每次錄入方法后做自加操作實(shí)現(xiàn)索引的偏移。)
- 循環(huán)中
call_class_loads調(diào)用 父本類+load
- 循環(huán)中
call_category_loads調(diào)用本類所有實(shí)現(xiàn)了load方法的分類的+ load方法
* 獲取當(dāng)前可以加載的分類列表 * 如果當(dāng)前類是可加載的 `cls && cls->isLoadable()` 就會(huì)調(diào)用分類的 load 方法 * 將所有加載過的分類移除 `loadable_categories` 列表 * 為 `loadable_categories` 重新分配內(nèi)存,并重新設(shè)置它的值 - 用
-
initializy
調(diào)用時(shí)機(jī) :第一次接收到消息的時(shí)候(objc_msgSend的時(shí)候)
調(diào)用順序:父類->本類->分類
- 本類繼承父類的實(shí)現(xiàn)
- 分類重寫后會(huì)覆蓋本類實(shí)現(xiàn),只會(huì)調(diào)用一個(gè)分類(分類存在
Compile Sources表中的最后一個(gè)會(huì)調(diào)用)
調(diào)用本質(zhì):objc_msgSend