美文网首页
iOS面试题与核心基础之load&initialize

iOS面试题与核心基础之load&initialize

作者: 十拿九稳啦 | 来源:发表于2022-04-01 03:23 被阅读0次

    知识点

    load

    Xcode compile sources 列表越往后的参与编译越晚

    调用时机

    • +load方法会在runtime加载类、分类时调用

    调用特点

    • 每个类、分类的+load,在程序运行过程中只调用一次
    • 通过函数指针分开直接调用,每个+load都会调用

    调用顺序

    • 先调用类的+load
      • 按照编译先后顺序调用(先编译,先调用)
      • 调用子类的+load之前会先调用父类的+load
    • 再调用分类的+load
      • 按照编译先后顺序调用(先编译,先调用)

    +load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用。
    如果是自己主动调用+load方法则是通过消息机制,先通过isa在类对象和元类对象的方法列表找,找不到则通过superclass指针在父类的类对象和元类对象找。不论通过isa还是superclass查找方法,最终都是后编译的分类的方法优先级比较高,而且消息机制方法调用的『覆盖特性』,找到方法就返回,所以只会调用一次+load方法。

    initialize

    调用时机

    • +initialize方法会在类第一次接收到消息时调用

    调用特点

    • 调用子类的+initialize必先调用父类的+initialize(runtime源码中主动先调用了父类的)

    • 一个类第一次接收消息时,就是+alloc,因而此时调用+initialize

    • 如果分类实现了+initialize,就会覆盖类本身的+initialize
      +initialize是通过消息机制调用的(objc_msgSend),由于消息机制的特性只调用最终方法列表的最前面第一个方法(最后参与编译的最后一个匹配方法),所以类和类的分类中如果同时存在+initialize只调用分类的+initialize

    • 父类的+initialize存在被多次调用的可能
      同样因为消息机制的特性,如果子类没有实现+initialize则会调用父类的+initialize,也就是说

    调用顺序

    • 先调用父类的+initialize,再调用子类的+initialize
      (先初始化父类,再初始化子类,每个类只会初始化1次)

    面试题

    1. category中有load方法么?load方法是什么时候调用的?
      有,在runtime加载类、分类时调用
    2. load、initialize方法的区别是什么?他们在分类中的调用顺序?以及出现继承时他们之间的调用过程
    3. +initialize可能被调用多次么?为什么?

    相关文章

      网友评论

          本文标题:iOS面试题与核心基础之load&initialize

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