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

知识点

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)