前沿:
上一篇探索了类与dyld的关联.接下来将要探索分析,类。分类,扩展的加载。
类的加载步骤是怎么样的呢?首先读取类的整个加载情况-> read_images
->readClass:``readClass读取的是地址
->name insert MAP
1.readClass探索
源码,使用 p/x cls ,x/4gx cls
当类加载调用readClass方法后获取 ,获取类的结构信息如下
第一次是没内存分配完毕,但是有指针存在。
。
结论:类在你加载的初期,内存没有分配完成,通过地址指针识别
的。
之后,执行到 realizeClassWithoutSwift
实现方法中。会去调用data()
当中经过一系列的变化,发现类最终的数据变化如图:
2 分类的加载
懒加载类与非懒加载类 区分 :当前类是否实现 load
方法
- 懒加载类情况 数据加载推迟到第一次消息的时候
lookUpImpOrForward-》realizeClassMaybeSwiftMaybeRelock-》realizeClassWithoutSwift-》methodizeClass
2: 非懒加载类情况 map_images的时候 加载所有类数据
_getObjc2NonlazyClassList readClass realizeClassWithoutSwift methodizeClass
attachCategories
当类加载时,进入到attachCategories
方法中,初始化了一个倒序的数组集合 method_list_t *mlists[ATTACH_BUFSIZ];
其中attachLists
方法中分3种情况:
- // 1.情况,当当前列表中无元素时,从 0 lists -> 1 list
// 此时是 一维数组
2.//2.当有有一个list时,
// 算法 list + list - 分类
准备工作:1创建一个LGPerson类。声明如下方法。并且实现
2.创建2个分类:
LGPerson+LGA.h
与LGPerson+LGB.h
其中:LGPerson+LGA.h声明实现方法如下: LGPerson+LGB.h 声明方法实现如下:
开始探索如下:
//据源码了解到如图:
memmove
方法是在做添加新元素的时候,整段向后平移,需要添加的容量,因此越晚添加的元素越在前面.
分类加载的时,调用class_rw_t::extAlloc
,源码如图:
//添加本类的rew
分类加载调用attachCategories
方法如图
会发现 mlist
是一个集合
最后跟随编译结果如下
结论:
主类,分类声明相同的方法时,会调用分类方法,而不会覆盖主类方法,切有多个不同名的分类,相同的方法,会调用最后一次加载的分类方法的。,其中:
只要有一个分类是->非懒加载分类 所有都会是, - rwe - 懒加载 重新去处理 LGPerson