对于OC
2大金刚+load/+initialze
都是线程安全的。常用来做一些提前操作。
+load
class或者catagory实现了此方法就一定会被调用,在runtime准备阶段就会调用。
现象
不同类调用顺序不定;父类先于子类;class会先于category;多个同class的category都实现的load都会调用,但顺序不定。
原理
是以2个数组(class,category)存放各指针。并且直接使用 load_method 调用函数内存地址进行调用(不是以objc_msgSend方式调用,所以没有普通类方法的特性),调用时会先递归调用父类的load函数,并且调用后标记为“已加载”。
+initialze
以objc_msgSend方式调用,所以与普通类方法非常相似,只是在class接收到第一个信息之前会先调用initialze(import不算给class发送信息),类似于懒加载特性。
初始化顺序
The order of initialization is as follows:
All initializers in any framework you link to.
All +load methods in your image.
All C++ static initializers and C/C++ attribute(constructor) functions in your image.
All initializers in frameworks that link to you.
官方:
源码解析:
对于Swift(需要先了解OC)
前言:
- swift1.2开始:class继承NSObjec也无法使用load。但swift代码中initialze可以被重写,也可以用OC的category方式添加load/initialze方法
- swift4.2开始:swift代码class 的initialze也不能被重写了,但可以用OC的category方式添加load/initialze方法
- swift5开始:swift的class只能用OC代码的category添加initialze。
Swift 使用load,initialze 总结图
Doable | swift-load | swift-initialze | bridgeToOC-load | bridgeToOC-initialze |
---|---|---|---|---|
swift1.2~4.2 | X | O | O | O |
swift4.2~5.0 | X | X | O | O |
swift5.0~? | X | X | X | O |
swift5之后的偏方总结(不再是全自动了)
方法1:使用OC在+load函数里,手写代码调用。(半自动)
这个比较详细,并且博主已经修改兼容swift5了。
这位同学的库中使用了C的宏,但是OC不能再给swift5的class扩展+load方法(参照上表)。所以这个库现在swift5会报错。可以自己删除load宏只用initialze的宏。