前言
在优秀的开发者眼里类充当着无比重要的一个角色,那么类的底层加载流程是什么样子的呢?下面我们一起来探究
- 储存过程中有三个重要类型:
rorwrwero:readOnly,只读类型的memory,处于沙河路径,术语为clean memory
rw: readAndWrit,读写memory,运行时内存(脏内存),app运行时的读写内存,术语dirty memory
rwe: readAndWritExtention,对rw的拓展(听起来似乎与类别有某种关系)
一、attachCategories探究
1、rwe赋值流程
那么探索从内存出发,根据名字初步推断类别很有可能储存在rwe中,objc底层源码中探索发现rwe赋值auto rwe = cls->data()->extAllocIfNeeded()调用了extAllocIfNeeded函数
cmd+左键点进去发现似乎是赋值流程
那么接下来我们只需要全局搜索哪些地方调用了
extAllocIfNeeded的赋值函数,就可以找到哪些情况对rwe做了赋值处理
2、调用了赋值函数的函数有哪些?
经过一些列的搜索发现以下函数
attachCategories //调用了1次 附加类别
objc_class::demangledName //调用了2次 demangled 名字
class_setVersion //调用了1次 类集版本
addMethods_finish //调用了1次 添加方法完成
BOOL class_addProtocol //调用了2次 类添加协议
objc_duplicateClass //调用了1次 objc复制类
我们这次的探究目的是研究分类,这些函数中与分类有关的貌似只有attachCategories
3.attachCategories探索
继续上探,看哪些方法调用了attachCategories
全局搜索发现只有两个函数调用了attachCategories方法
attachToClass //附加到类
load_categories_nolock //加载分类->解锁
既然只有两个我们就一个一个来探索,非常的nice
3.1、attachToClass(翻译意思似乎是给类添加什么东西,感觉跟分类似乎关系非常的密切)
探索哪些方法调用了attachToClass函数,全局搜索发现只被调用了三次而且都在一个函数methodizeClass里,很完美
methodizeClass //整理类
很完美
4、methodizeClass探索
通过3.1我们发现三次调用
attachToClass函数,其中两次是在if语句里previously存在时调用的
那么previously是什么东西?又是从哪里来的呢?出于好奇我们一探究竟
找到出处发现
previously是在methodizeClass函数中的class类型的一个参数
4.1、那么哪些函数调用了methodizeClass函数呢?继续进行全局搜索,只有realizeClassWithoutSwift(类加载函数)调用了methodizeClass函数,而且也只是一个参数
继续向上层查找
全是
nil...看样子可能苹果底层开发者预留的备用类
OK好奇心已经满足,我们回到正途继续探索
5.类别的最终出处realizeClassWithoutSwift(类加载函数)
由4.1探索过程中我们已经发现了调用
methodizeClass函数的上一层方法是realizeClassWithoutSwift---- 类加载函数
总结、最终有回归到了类的加载中来,我们不知不觉中已经理清楚了分类加载的一条线
流程如下
graph TD
realizeClassWithoutSwift --> methodizeClass --> attachToClass --> attachCategories --> extAllocIfNeeded
第二条线路 --> load_categories_nolock --> attachCategories --> extAllocIfNeeded
二、attachCategories流程之load_categories_nolock流程
写字好累,经过层层探索终于得到第二条线的流程很完美
得出完整的流程图
graph TD
realizeClassWithoutSwift --> methodizeClass --> attachToClass --> attachCategories --> extAllocIfNeeded
_objc_init_image --> _read_images --> load_categories_nolock --> attachCategories --> extAllocIfNeeded
map_images --> map_images_nolock --> _read_images --> load_categories_nolock --> attachCategories --> extAllocIfNeeded
_objc_init --> load_images --> loadAllCategories --> load_categories_nolock --> attachCategories --> extAllocIfNeeded