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