对于 iOS 开发者而言,+load()
,+initialize()
,-init()
方法应该并不陌生,但是,对于这些方法的调用逻辑和顺序,可能会偶有疑惑,本文通过 demo 的方式,来探究一下这几个方法
+ load()
+load()
方法是当类或分类被添加到 Objective-C runtime
时被调用的,实现这个方法可以让我们在类加载的时候执行一些类相关的行为,子类的 +load
方法会在它的所有父类的 +load()
方法之后执行,而分类的 +load()
方法会在它的主类的 +load()
方法之后执行。但是不同的类之间的 +load()
方法的调用顺序是不确定的
我们先创建一个 TestClass
类,然后在创建一个继承自该类的子类 TestClassSubClass
,和两个 TestClass
的分类 TestClass+Z
, TestClass+Y
,分别在这几个类中实现 +load()
方法,并打印输出,然后在 main()
中也写一个输出语句,运行程序,我们来看一下输出
int main(int argc, char * argv[]) {
@autoreleasepool {
NSLog(@" %s", __func__);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
如我们所看到的,+load()
的调用是在 main()
函数之前,并且在整个 APP 运行过程中只会被调用一次,对 +load()
方法进行调用,是直接使用函数内存地址的方式 (load_method)(cls, SEL_load);
而不是使用发送消息 objc_msgSend
的方式,父类 TestClass
的 +load()
方法最先被调用,而后是子类和分类,对于多个分类的 +load()
的调用顺序的先后,取决于编译顺序,测试一下,我们在 Bulid Phases->Compile Sources
调整分类的编译顺序
会看到 TestClass+Z
的 +load()
方法先于 TestClass+Y