前言
我们将3个类A、B、C分别表示为父类、子类、子类的分类来了解load和initialize
注意:
1.下文中所说的类都是直接或者间接继承NSObject
2.这里只分析的类中实现+load和+initialize方法的情况,不包含主动调用
使用场景
+load方法通常用来进行Method Swizzle
+initialize方法一般用于初始化全局变量或静态变量
调用时机
load方法会在mian函数之前调用,会循环调用所有类(包括分类)的 +load 方法
initialize的调用是在第一次主动使用当前类的时候
调用次数
- load和initialize在类中只要实现都会调用一次(非super,非主动调用)
执行的顺序
+load方法:A -> B -> C ,即 父类 -> 子类 -> 分类
+initialize方法: A -> C ,即 父类 -> 分类
方法实现方式
+load使用函数内存地址的方式 (*load_method)(cls, SEL_load);
+initialize使用发送消息 objc_msgSend 的方式
子类和父类
load方法不会考虑对NSObject的继承,所有类实现load方法就会实现,没有也不会沿用父类方法
子类不实现initialize方法,父类实现initialize方法,子类沿用父类的方法
比如 父类A 中分别实现+load、+initialize方法,子类B中不实现+load、+initialize方法
执行的顺序 [A load] -> [A initialize] -> [A initialize]
类和类别
本类和类别的+load方法存在就实现,不存在就不实现
类别中的+initialize方法会覆盖本类的方法,只执行一个类别的+initialize方法
安全性
- load和initialize方法内部使用了锁,所以都是线程安全的
其他注意点
- 在方法中如果使用super,load执行的顺序和次数依旧保持不变,但是initialize的执行顺序和次数会变动,会调用多次,所以开发中尽量不要使用super
2.在A、B、C的其中两个类的+load方法中去都实现方法的替换操作,由于方法置换2次使置换失效,所以+load中替换等操作加上dispatch_once保持执行一次
3.不要去主动去调用load或者initialize方法,会失去他们调用的“唯一性”
4.load方法不会直接触发initialize的调用,但是不要再+load出现self等类方法的调用,会使initialize的方法提前出现,原因是使该类的第一条消息提前发生