load
调用时机:app启动时 动态库加载的时候(在main函数之前调用)
调用顺序:父类->父类 -> 本类 -> 分类
- 其中没有实现
+load方法的类就跳过
- 如:入父类a->父类b->本类->分类(其中
b继承a且b没有实现+load则调用:父类a->本类->分类)
- 全部分类都会调用,其调用顺序由
Compile Source顺序决定
具体剖析: 直接调用IMP 函数指针
类加载的时候,先调用
objc_init(void)每当有新的 library 被 map 到
runtime时,调用load_images方法。-
load_images-
perpar_load_methods()主类的父类和自身添加到全局静态结构体 loadable_list 中之后,添加主类的分类,将分类添加到全局静态结构体loadable_categories中。所以子类优先分类。- 上了线程安全:递归锁 (
recursive_mutex_t)
- 添加本类(本类中的
include的类 且没有执行过+load)及父类。。。父类到loadable_List中。
(递归调用schedule_class_load-> 父类。。。添加到loadable_List) - 添加
category到loadabel_categorys中
- 上了线程安全:递归锁 (
-
call_load_methods();当library加载完成后,需要调用call_load_methods- 用
objc_autoReleasePoolPush创建一个pool。
-
do while循环调用父类->本类->分类 的+load方法。(loadable_classes_used->为一个全局的指针偏移变量并在每次录入方法后做自加操作实现索引的偏移。)
- 循环中
call_class_loads调用 父本类+load
- 循环中
call_category_loads调用本类所有实现了load方法的分类的+ load方法
* 获取当前可以加载的分类列表 * 如果当前类是可加载的 `cls && cls->isLoadable()` 就会调用分类的 load 方法 * 将所有加载过的分类移除 `loadable_categories` 列表 * 为 `loadable_categories` 重新分配内存,并重新设置它的值 - 用
-
initializy
调用时机 :第一次接收到消息的时候(objc_msgSend的时候)
调用顺序:父类->本类->分类
- 本类继承父类的实现
- 分类重写后会覆盖本类实现,只会调用一个分类(分类存在
Compile Sources表中的最后一个会调用)
调用本质:objc_msgSend