美文网首页面试合集
+load 和+initialize的区别

+load 和+initialize的区别

作者: 写代码的小农民 | 来源:发表于2021-01-06 19:17 被阅读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......
    });
}

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

相关文章

网友评论

    本文标题:+load 和+initialize的区别

    本文链接:https://www.haomeiwen.com/subject/gjrooktx.html