iOS load,initialze及swift5的曲线救国总结笔记

4,815 阅读2分钟

对于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.

官方:

developer.apple.com/documentati…

源码解析:

blog.leichunfeng.com/blog/2015/0…

对于Swift(需要先了解OC)

前言:

  1. swift1.2开始:class继承NSObjec也无法使用load。但swift代码中initialze可以被重写,也可以用OC的category方式添加load/initialze方法
  2. swift4.2开始:swift代码class 的initialze也不能被重写了,但可以用OC的category方式添加load/initialze方法
  3. swift5开始:swift的class只能用OC代码的category添加initialze。

stackoverflow.com/questions/2…

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了。

medium.com/post-mortem…

这位同学的库中使用了C的宏,但是OC不能再给swift5的class扩展+load方法(参照上表)。所以这个库现在swift5会报错。可以自己删除load宏只用initialze的宏。

www.jianshu.com/p/4bebaa5b4…

方法2:(推荐) 通过runtime遍历类类列表找到对应遵从协议的类,并调用。(全手动)

jordansmith.io/handling-th…