美文网首页ios面试汇总
30.load和initialize

30.load和initialize

作者: 小笨憨 | 来源:发表于2017-08-31 15:10 被阅读0次

    load和initialize的共性

    • 1.都是为了应用运行提前创建合适的运行环境在不考虑开发者主动使用的情况下,系统最多会调用一次
    • 2.在不考虑开发者主动使用的情况下,系统最多会调用一次
    • 3.方法的执行顺序是先父类后子类
    • 4.在使用时都不要过重地依赖于这两个方法,除非真正必要

    load的相关特点

    1.运行时机

    load的执行时机在App启动时,而且是在main()之前,但并不能保证所有类都加载完成且可用。因此此时C++静态初始化程序还没有运行,但你链接到的framework在此点确保完全加载了。

    2.加载的内容

    你链接的framework->镜像中的所有load方法->镜像中所有C++静态初始化和C/C++attribute(构造函数)函数->链接到你的framework

    3.执行顺序

    一个类的load方法不用写明[super load],父类也会执行load方法,并且是先父类后子类的顺序。
    Categoryload方法也会执行,并且是先类后分类的顺序。

    4.在Category中的特性

    load方法在category中的使用有另外一个特性。对于某个类,当category中重写某个方法时,只会执行category中的此方法,并不会执行原类中的此方法。但在category中重写load方法后并不会影响其原来类的load方法执行,而是如上面所说的先类后分类的顺序执行。

    5.autorelease

    load中必要时还要自己负责做autorelease处理

    6.swift中的load

    桥接到Objective-CSwift类的加载方法的自定义实现不会自动调用。

    7.源码

    你可以看到在运行时如何查找的load方法作为一种特殊情况_class_geLoadMethodobjc-runtime-new.mm,并直接调用它call_class_loads的objc-loadmethod.mm

    initialize的相关特性

    1.运行时机

    在收到第一条消息之前初始化该类,初始化每个类只调用一次。与load的加载时机不相同,类似于懒加载的方法,所以也可能根本不会被调用。
    当一个类首次加载时,+initialize不调用。当消息发送到一个类时,运行时首先检查是否+initialize已经被调用。如果没有,则在继续发送消息之前调用它。

    2.执行顺序

    顺序为先父类后子类,所以超类在他们的子类之前收到这个消息。

    3.父类和子类

    load不同,如果子类不实现initialize,或者如果子类明确调用[super initialize],则可以多次调用超类实现。如果要保护自己不要多次运行,可以按照以下方式构建您的实现:

    + (void)initialize {
      if (self == [ClassName self]) {
        // ... do the initialization ...
      }
    }
    

    4.线程安全

    运行时以线程安全的方式将初始化消息发送给类。也就是说,初始化由第一个线程运行以将消息发送到类,并且尝试向该类发送消息的任何其他线程将阻塞,直到初始化完成。所以initialize的运行过程中是能保证线程安全的。

    5.运行环境

    load不同,load的运行环境还是相对比较危险的,而在initialize方法收到调用时,运行环境已经基本健全了。所以,initialize的适用场景要比load多。

    6.源码

    运行时initialize_class_initialize函数中发送消息objc-initialize.mm。您可以看到它用于objc_msgSend发送它,这是普通的消息发送功能。

    相关文章

      网友评论

        本文标题:30.load和initialize

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