iOS底层学习-day-6
前言-OC语法篇
我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天,这几天加班,没时间写和发布,趁着任务做完赶紧更新几篇。
问题
Category中有load方法吗?load方法是什么时候调用的?load 方法能继承吗?
- 有load方法
- load方法在runtime加载类、分类的时候调用
- load方法可以继承,但是一般情况下不会主动去调用load方法,都是让系统自动调用
load、initialize方法的区别什么?
- 调用方式
- load是根据函数地址直接调用
- initialize是通过objc_msgSend调用
- 调用时刻
- load是runtime加载类,分类的时候调用(只会调用一次)
- initialize是类第一次接收到消息的时候调用,每一个类智慧initialize一次(父类的initialize方法可能会被调用多次)
它们在category中的调用的顺序?
- load
- 先调用类的load
- 先编译的类,优先调用load
- 调用子类的load之前,会优先调用父类的load
- 再调用分类的load
- 先编译的分类,优先调用load
- 先调用类的load
- initialize
- 先初始化父类
- 再初始化子类(可能最终调用父类的initialize方法)
+ (void)load 调用
load是在runtime运行时的时候,就动态加载进来的,在分类中重写load方法,还是会先调用原来的load方法
-
调用顺序
- 先调用类的+load 再调用分类的+load方法,按照编译先后顺序调用(先编译,先调用),调用子类的+load 之前会先调用父类的+load,如果父类已经调用过了,那么就不调用了,因为load只调用一次
- 再调用分类的+load,按照编译先后顺序调用(先编译,先调用)
- 为什么先加载父类的load方法,因为是将父类先加载方法列表前面,再放子类的load方法
-
+test 和 +load 方法的区别
- 因为它直接调用类的+load了
- 而自己写的+test方法是调用objc_msgSend([Person class],@selector(test))直接用消息机制调用,也就是isa一层一层往下找
+ initialize
- 调用顺序
- Class objc_getClass(const char *aClassName)
- 先调用父类的+initialize,再调用子类的+initialize,因为内部有做先调用父类initialize,再调用子类initialize
objc_msgSend([MJPerson class], @selector(initialize));
objc_msgSend([MJStudent class], @selector(initialize));
- (先初始化父类,再初始化子类,每个类只会初始化1次)
- +initialize和+load
- +initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点:
- 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
- 如果分类实现了+initialize,就覆盖类本身的+initialize调用
- +initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点:
- +initialize的原码分析类似于
if (!sutdentInitialized) {
if (!personInitialized) {
objc_msgSend([MJPerson class], @selector(initialize));
personInitialized = YES;
}
objc_msgSend([MJStudent class], @selector(initialize));
sutdentInitialized = YES;
}