1.load方法什么时候调用?
load方法在runtime加在类和分类的时候只调用一次
Person.h
Person+Test1.h
Person+Test2.h
如果Person 和两个分类都实现了+load方法。那么都会添加进Peron的方法列表里面。不够后面编译的方法会执行
runtime源码: 加载类的时候
do {
// 1. Repeatedly call class +loads until there aren't any more
while (loadable_classes_used > 0) {
/// 先加载类的方法
call_class_loads();
}
// 2. 再加在分类的方法
more_categories = call_category_loads();
// 3. Run more +loads if there are classes OR more untried categories
} while (loadable_classes_used > 0 || more_categories);
1.为什么load方法 每一个都会调用呢?
因为load方法不是通过objc_msgSend 而是通过另外一个方法 就是
call_class_loads 这个方法。他会直接找到类的方法调用 在便利category 然后调用
而test方法是通过 objc_msgSend 通过isa指针来查找方法的
2.load方法的调用顺序
源码有这么一句
// Ensure superclass-first ordering
schedule_class_load(cls->superclass);
add_class_to_loadable_list(cls);
Ensure superclass-first ordering 确保父类首先加载
1.按照编译的顺序调用load方法
2.如果有父类首先调用父类的方法
3.首先调用类的load方法 在调用category的方法
1. initialize方法什么时候调用?
对于一个类来说 只要 第一次接受到消息 就必定会调用initialize方法 方法[自己活着父类实现的话]
initialize方法在类第一次接受到消息的时候调用
而且是消息发送机制 [category的调用在本类之前]
2. initialize方法的调用顺序。对于自己来说 只调用一次
先调用父类的在调用子类的
先category的 在本类
对于初始化自己。如果自己没有 那么就会调用父类的initialize方法
如果一个类有很多子类。那么就有可能会调用很多次
2.load initialize 的区别
执行时机
+(void)load在runtime加载类的时候调用
+(void)initialize在类的方法第一次被调时执行
若自身未定义,是否沿用父类的方法?
+(void)load 否
+(void)initialize 是
类别中的定义
+(void)load全都执行,但后于类中的方法 覆盖类中的方法,
+(void)initialize只执行一个
1.调用方式
1> load是根据函数地址直接调用
2> initialize是通过objc_msgSend调用
2.调用时刻
1> load是runtime加载类、分类的时候调用(只会调用1次)
2> initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被调用多次)
load、initialize的调用顺序?
1.load
1> 先调用类的load
a) 先编译的类,优先调用load
b) 调用子类的load之前,会先调用父类的load
2> 再调用分类的load
a) 先编译的分类,优先调用load
2.initialize
1> 先初始化父类
2> 再初始化子类(可能最终调用的是父类的initialize方法)