+load方法
我们先来看下load方法是什么时间加载的
// 我们创建一个Person对象
@interface DDPerson : NSObject
@end
@implementation DDPerson
+ (void)load {
NSLog(@"DDPerson ------------ load");
}
@end
// 创建 Eat 分类
@interface DDPerson (Eat)
@end
@implementation DDPerson (Eat)
+ (void)load {
NSLog(@"Eat ------------ load");
}
@end
// 创建 Sing 分类
@interface DDPerson (Sing)
@end
@implementation DDPerson (Sing)
+ (void)load {
NSLog(@"Sing ------------ load");
}
@end
主函数中什么都不写直接运行程序
// 主函数中我们什么都不写 直接运行
int main(int argc, const char * argv[]) {
@autoreleasepool {
}
return 0;
}
结果如下:
2021-04-23 14:56:25.070127+0800 category[49037:2199567] DDPerson ------------ load
2021-04-23 14:56:25.070553+0800 category[49037:2199567] Eat ------------ load
2021-04-23 14:56:25.070601+0800 category[49037:2199567] Sing ------------ load
Program ended with exit code: 0
结论:
load方法是在Runtime加载类和分类的时候调用的,整个程序的生命周期中,只调用一次
接下来我们一起看下假如有子类的情况。接着上方,我们给Person添加两个子类
// 创建Teacher子类
@interface DDStudent : DDPerson
@end
@implementation DDStudent
+ (void)load {
NSLog(@"DDStudent ------------ load");
}
@end
// 创建Teacher子类
@interface DDTeacher : DDPerson
@end
@implementation DDTeacher
+ (void)load {
NSLog(@"DDTeacher ------------ load");
}
@end
运行结果:
2021-04-23 15:10:44.507480+0800 category[49130:2209977] DDPerson ------------ load
2021-04-23 15:10:44.507832+0800 category[49130:2209977] DDStudent ------------ load
2021-04-23 15:10:44.507885+0800 category[49130:2209977] DDTeacher ------------ load
2021-04-23 15:10:44.507919+0800 category[49130:2209977] Sing ------------ load
2021-04-23 15:10:44.507952+0800 category[49130:2209977] Eat ------------ load
Program ended with exit code: 0
结论:
Runtime首先会加载类及其子类的load方法,然后才加载分类中的load方法
其实编译顺序还跟 Targets - Build Phases中文件位置有关,大家可以调换一下看看
+load方法总结
- load方法会在Runtime加载类和分类的时候调用
- 类和分类的load方法在运行程序过程中只调用一次
- 先调用类的load方法,按照编译先后顺序调用(先编译,先调用),调用子类的+load之前会先调用父类的+load
- 再调用分类的+load,按照编译先后顺序调用(先编译,先调用)
+initialize方法
我们可以把上边load方法改为initialize方法重新运行程序,然后看下调用步骤。我这里直接说结论了
+initialize方法总结
- +initialize方法会在类第一次接收到消息时调用
- 先调用父类的+initialize,然后在调用子类的+initialize(先初始化父类,再初始化子类,每个类只会初始化1次)
- +initialize和+load 最大的区别在于 +initialize是通过objc_msgSend进行调用的,所以有下边两个特征
- 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
- 如果分类实现了+initialize,就覆盖类本身的+initialize调用
如果有误,望大家指出,大家加油❀❀❀❀❀