+load 和+initialize的区别

首先调用时机不同,决定了完全不同的调用原理,形成了很大的差异。

写在前面的话

最好不要在+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......
    });
}

如有错误或者新的见解欢迎在评论区约谈...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容