+load方法简介
+load方法在这个类的文件被程序装载时调用。只要是在Compile Sources中出现的文件总是会被装载,不管这个类是否被用到过。在一个程序开始运行之前(在main函数开始执行之前),类文件开始被程序加载,+load方法就会开始被执行;因此+load方法总是在main函数之前调用。
疑问:
objc中类的+load方法是怎么被调用的?
为什么父类的+load比子类的+load先执行?
为什么宿主类的+load比分类的+load先执行?
通过分析objc/runtime源码消除以上疑问。
声明
@interface NSObject
...
+ (void)load;
...
@end
示例代码:
@interface Person : NSObject
@end
@implementation Person
+ (void)load {
NSLog(@"%s", __func__);
}
@end
@interface Woman : Person
@end
@implementation Woman
+ (void)load {
NSLog(@"%s", __func__);
}
@end
@implementation Woman (XYExtension)
+ (void)load {
NSLog(@"%s", __func__);
}
@end
@implementation Woman (XYExtension1)
+ (void)load {
NSLog(@"%s", __func__);
}
@end
输出结果:
2019-06-18 15:23:59.862941+0800 objc-test[17947:205876] +[Person load]
2019-06-18 15:23:59.863319+0800 objc-test[17947:205876] +[Woman load]
2019-06-18 15:24:02.215828+0800 objc-test[17947:205876] +[Woman(XYExtension1) load]
2019-06-18 15:24:03.911969+0800 objc-test[17947:205876] +[Woman(XYExtension) load]
调用顺序
根据上面的示例可以看到,宿主类的load方法会先被调用,然后再调用分类的load方法,其中宿主类中父类的load方法先调用,非父子类型的按照Compile source中的顺序调用,分类的load方法根据Compile source中的顺序调用。
load方法的调用栈
load方法函数调用栈.png
从我们可以看到源码的位置开始,依次调用的顺序为:
load_images -> call_load_methods -> call_class_loads -> +load
这三个函数的源码分别为:
/**************************