iOS 懒加载类和非懒加载类

341 阅读1分钟

学习OC底层的过程中,发现类的结构初始化是通过realizeClassWithoutSwift实现的。 之前看过一些资料中写道:
未初始化的类:cls->data() ---> class_ro_t
初始化的类:cls->data() ---> class_rw_t ---> class_ro_t(在新版本中增加了class_rw_ext_t)

很多资料中都是通过分析第一次类方法调用,发现了类的初始化过程。其实在底层中,系统将OC的类分为了懒加载和非懒加载两种。

image.png

可以看到注释中明确指出了,实现了+ load方法时就是非懒加载类。 那么很明显:
非懒加载类: 在map_images中初始化
懒加载类: 在第一次类方法调用的查找过程中被调用。和initialize方法在一起
特殊情况: 当类别中实现了+ load方法,那么就会在load_images中触发初始化方法。

既然+ load方法影响了类的加载,那么是否类别的attachCategories也会受到+ load方法影响。经过代码调试得到以下四种结果
1:主类实现+分类实现:load_images -> loadAllCategories -> .... -> attachCategories
2:主类实现+分类实现:启动流程不执行attachCategories
3:主类实现+分类实现:启动流程不执行attachCategories
4:主类实现+分类实现:启动流程不执行attachCategories

在2、3、4三种情况中,realizeClassWithoutSwift方法内部打印class_ro_t里面发现已经包含了分类的方法, 而isa.data()是从mach-o中读取出来的,那么应该编译链接的时候就已经存在mach-o中了。

在第二种实现中,如果有多个分类都实现了+ load方法,那么同样是会调用attachCategories的。