iOS底层学习——Category(二)

+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调用

如果有误,望大家指出,大家加油❀❀❀❀❀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值