文章目录
OC对象 - +load、initialize方法
1. +load方法
1.1 调用时机
- +load方法会在runtime加载类、分类时调用
- 每个类、分类的+load,在程序运行时只调用一次
1.2 调用顺序
- 先调用父类的+load
- 按照编译先后顺序调用(先编译,先调用)
- 调用子类的+load之前会先调用父类的+load
- 再调用分类的+load
- 按照编译先后顺序调用(先编译,先调用)
1.3 码上验证

从类文件列表看到,ZSXPerson在其两个分类的后面编译的,但是它的+load始终是最先调用的
1.4 调用方式
从源码可以看出
+load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用
2. initialize方法
2.1 调用时机
- +initialize方法会在类第一次接收到消息时调用
2.2 调用顺序
- 先调用父类的+initialize,再调用子类的+initialize
- 先初始化父类,再初始化子类,每个类只会初始化1次
注:如果有分类的情况,
分类的+initialize方法会覆盖掉类的+initialize方法
2.3 码上验证
2.3.1 验证父类和子类的情况
ZSXStuden是ZSXPerson的子类,给ZSXStuden发送消息,先执行父类ZSXPerson的+initialize方法,再执行子类ZSXStuden的+initialize方法

2.3.4 验证含有分类的情况
ZSXStuden是ZSXPerson的子类,ZSXPerson有分类ZSXPerson+_11,分类中也实现了+initialize方法。给ZSXStuden发送消息,因为分类方法覆盖了类的方法,会先执行父类分类ZSXPerson+_11的+initialize方法,再执行子类ZSXStuden的+initialize方法

2.4 调用方式
我们注意到,+initialize实在第一次收到消息时调用,可以推断出他是跟runtime有关的,所以:
+initialize是通过objc_msgSend进行调用的
3. +load、initialize方法的区别
+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点
- 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
- 如果分类实现了+initialize,就覆盖类本身的+initialize调用
3.1 验证+initialize可能被调用多次
因为+initialize走了runtime机制调用,我们知道,子类收到消息时,如果自身找不到方法实现,会到父类中继续查找
- 我们多创建一个
ZSXPerson的子类ZSXTeacher ZSXPerson有2个子类:ZSXStuden和ZSXTeacherZSXTeacher中没有+initialize方法- 我们分别给
ZSXStuden和ZSXTeacher发送消息,查看+initialize方法调用情况、

@oubijiexi
本文详细解析了Objective-C中+load和initialize方法的调用时机、顺序,强调了+load仅在类加载时调用一次且遵循特定顺序,而initialize在类首次接收到消息时调用,子类的initialize可能因父类或分类的存在而被多次调用。
738





