问题1: load 和 initialize 区别是什么?
官方:运行时,添加类或者分类的时候调用。实现此方法以在加载时执行特定于类的行为。
+ load :
- 添加类, 分类里面包含
+ load
方法时候调用, 即使类没有并没有加载
举例 - 自动调用, 内部用锁, 线程安全
+ initialize :
官方: 在类收到第一条消息之前初始化它。
- 添加类, 分类里面包含
+ initialize
方法时, 是在第一次发送消息objc_msgSend
的时候进行的调用, 没有消息发送不执行。
举例 - 自动调用, 内部用锁, 线程安全
调用情况
-
+load
: 是在dyld
回调load_images
中进行调用的,这个回调是在_objc_init的过程中进行注册的。 -
initialize
: 是在第一次发送消息objc_msgSend
的时候进行的调用。
调用顺序: load
> initialize
执行次数
-
+ load
: 只有1次, 即使多次调用同一类 -
+ initialize
: 0 或 1- 0: 没有消息发送
objc_msgSend
- 1: 消息发送正常调用, 即使多次调用同一类
- 0: 没有消息发送
多类无继承关系
举例 举例-
+ load
: 按照编译顺序, 进行加载 -
+ initialize
: 谁先执行objc_msgSend
, 先执行+ initialize
子类实现
- 子类实现
+ load
: 先调用父类+load
方法, 再子类+load
方法
举例 - 子类实现
+ initialize
: 先调用父类+ initialize
方法, 再+ initialize
方法
分类实现
- 分类实现
+ load
:主类 +load
→子类+load
→分类 +load
分类+ load - 多分类实现
+ load
: 跟编译顺序有关, 谁在前面先执行
- 分类实现
+ initialize
: 跟编译顺序有关, 只执行最后编译的分类
- 子类实现
+ initialize
: 主类线+ initialize
先走 → 子类线+ initialize
使用场景
使用场景参考
-
+ load
: 一般是用来交换方法Method Swizzle,由于它是线程安全的,而且一定会调用且只会调用一次,通常在使用UrlRouter的时候注册类的时候也在+load方法中注册。 -
+ initialize
: 处理一些不方便在编译期吗处理的初始化的对象进行赋值,或者说对一些静态常量进行初始化操作。
网友评论