load
調(diào)用時(shí)機(jī):app啟動(dòng)時(shí) 動(dòng)態(tài)庫(kù)加載的時(shí)候(在main
函數(shù)之前調(diào)用)
調(diào)用順序:父類->父類 -> 本類 -> 分類
- 其中沒(méi)有實(shí)現(xiàn)
+load
方法的類就跳過(guò)
- 如:入父類a->父類b->本類->分類(其中
b
繼承a
且b
沒(méi)有實(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
的類 且沒(méi)有執(zhí)行過(guò)+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 方法 * 將所有加載過(guò)的分類移除 `loadable_categories` 列表 * 為 `loadable_categories` 重新分配內(nèi)存,并重新設(shè)置它的值
- 用
-
initializy
調(diào)用時(shí)機(jī) :第一次接收到消息的時(shí)候(objc_msgSend
的時(shí)候)
調(diào)用順序:父類->本類->分類
- 本類繼承父類的實(shí)現(xiàn)
- 分類重寫(xiě)后會(huì)覆蓋本類實(shí)現(xiàn),只會(huì)調(diào)用一個(gè)分類(分類存在
Compile Sources
表中的最后一個(gè)會(huì)調(diào)用)
調(diào)用本質(zhì):objc_msgSend