对于 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

本文通过示例详细解析了iOS中类的+load、+initialize方法和对象的-init方法的调用顺序和特点。+load在类加载时调用,不受懒加载影响;+initialize在类或其子类接收到第一条消息前调用,具有懒加载特性。-init方法在实例化对象时调用,遵循父类到子类的顺序。所有方法都是线程安全的,适合进行特定初始化操作。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



