+load 和+initialize的区别
2021-01-06 本文已影响0人
写代码的小农民
首先调用时机不同,决定了完全不同的调用原理,形成了很大的差异。
写在前面的话
最好不要在+load里初始化第三方的库,很有可能app启动耗时很久甚至失败。
自己的业务逻辑多使用+initialize替代+load。
调用时机
-
+load 方法是在runtime加载类和分类的时候自动调用的,只会调用一次。不通过message_send()触发, 而是通过load_method这个结构体里的IMP直接执行,不符合OC的 消息分发机制。
-
+initialize方法会在类第一次接收到消息时被调用,如果子类没有实现该方法,父类的+initialize方法,会被调用多次。通过message_send触发,符合OC的消息分发机制。
在继承和分类里的调用顺序。
- +load的调用顺序
1.先调用类的+load
按照编译先后顺序调用(先编译,先调用)
调用子类的+load之前会先调用父类的+load
2.再调用分类的+load
按照编译先后顺序调用(先编译,先调用)和继承没有关系
- +initialize的调用顺序
1.在调用子类的+initialize方法时会先调用父类的+initialize方法,造成父类的+initialize方法会调用多次,但是并不会使父类初始化多次,每调用一次初始化的都是子类调用者的实例对象,所以每个类还是只被初始化一次(比如不同子类初始化之前,父类只会被初始化一次)。
2.分类会覆盖原类+initialize方法的实现。
用途
- +load 常用于在main函数之前初始化一些重要的数据,但会影响启动时间。 经常配合一次函数使用,防止手动多次调用+load方法。
+ (void) load
{
static dispatch_once_t token;
dispatch_once(&token, ^{
// init......
});
}
- initialize 用于懒加载一些类的初始化信息,或者注册KVO监听,注册通知,runtime方法交换。 经常配合一次函数使用,子类多次调用时防止一些数据被多次创建,推荐使用。
+ (void)initialize
{
static dispatch_once_t token;
dispatch_once(&token, ^{
// init......
});
}
如有错误或者新的见解欢迎在评论区约谈...