声明:本文仅供记忆使用,并不适合新手小白观看
+load方法
- +load方法会在runtime加载类、分类时调用,每个类、分类的+load,在程序运行过程中只调用一次
- +load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用
- 调用顺序
- 先调用类的+load
按照编译先后顺序调用(先编译,先调用)
调用子类的+load之前会先调用父类的+load - 再调用分类的+load
按照编译先后顺序调用(先编译,先调用)
- runtime代码调用
- objc4源码解读过程:objc-os.mm
_objc_init
load_images
prepare_load_methods
schedule_class_load
add_class_to_loadable_list
add_category_to_loadable_list
call_load_methods
call_class_loads
call_category_loads
(*load_method)(cls, SEL_load)
- objc4源码解读过程:objc-os.mm
+initialize方法
-
+initialize方法会在类第一次接收到消息时调用
-
+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点
如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
如果分类实现了+initialize,就覆盖类本身的+initialize调用 -
调用顺序
- 如果父类没有initialize过,先调用父类的
objc_msgSend(+initialize),就相当于走消息机制,如果父类分类实现了+initialize方法会调用分类的+initialize; - 再调用子类的
objc_msgSend(initialize),就相当于走消息机制,如果子类分类实现了+initialize方法会调用分类的+initialize;
具体看伪代码
- 如果父类没有initialize过,先调用父类的
-
伪代码
1
2
3
4
5
6
7
8
9
10
11lookUpImpOrForward {
查询方法操作…
if (!子类Initialized) {
if (!父类Initialized) {
objc_msgSend(父类,@selector(initialize));
父类Initialized = YES;
}
objc_msgSend(子类,@selector(initialize));
子类Initialized = YES;
}
} -
runtime代码调用
- objc4源码解读过程
objc-msg-arm64.s
objc_msgSend - objc-runtime-new.mm
class_getInstanceMethod
lookUpImpOrNil
lookUpImpOrForward
_class_initialize
callInitialize
objc_msgSend(cls, SEL_initialize)
- objc4源码解读过程