知识点
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次)
面试题
- category中有load方法么?load方法是什么时候调用的?
有,在runtime加载类、分类时调用 - load、initialize方法的区别是什么?他们在分类中的调用顺序?以及出现继承时他们之间的调用过程
-
+initialize
可能被调用多次么?为什么?
网友评论