上篇文章我们了解了类的加载和分类的数据准备 这篇我们继续分析分类的加载时机以及是如何加载到类中的
当类加载时,进入到attachCategories方法中,初始化了一个倒序的数组集合 method_list_t *mlists[ATTACH_BUFSIZ];

attachLists方法:将分类加载到主类上

三种情况:
part1:目前有多个list,又加入多个listlists中存在多个list,这时又要插入多个list,
a. 生成newCount:总的list个数
b. 根据newCount创建一个新的Array
c. memmove:将oldList整段平移
d.memcpy:将新的lists放到首位memcpy(参数1:从什么位置,参数2:插入什么,参数3:插入的长度)
part2:向list数组中添加一个list,一维数组
a.list数组中添加一个list
part3:向list数组(目前只有一个元素)中添加多个list(list数组),二维数组
a. 生成newCount:总的list个数
b. 根据newCount创建一个新的Array
c. array()->lists[addedCount] = oldList;:将oldList放到末尾
d.memcpy:将新的lists放到首位memcpy(参数1:从什么位置,参数2:插入什么,参数3:插入的长度)
分类的加载流程:
realizeClassWithoutSwift -> methodizeClass -> attachCategories -> attachLists
主类与分类加载数据的时机
分类attachCategories执行时机
全局搜索 attachCategories方法,发现只有在两个地方调用了
1.attachToClass方法中调用

2. load_categories_nolock方法中调用

在这两个方法中打上断点就会发现是由load_categories_nolock -> 执行到的attachCategories方法中。
在attachCategories方法处打断点,并在控制台bt输出堆栈信息

那么在bt堆栈信息中我们看到 load_images -> loadAllCategories -> load_categories_nolock -> load_categories_nolock -> attachCategories

懒加载类/非懒加载类 和 懒加载分类/非懒加载分类
在上述分析中,主类和分类都实现了load方法,即都是非懒加载,那么如果有两个分类,其中主类是非懒加载类,分类有一个是懒加载类一个是非懒加载类呢?
或者主类是懒加载,分类是非懒加载类;又或者主类和分类都为懒加载类呢?
添加一个主类LGPerson,分类一:LGA,分类二:LGB
懒加载类与懒加载分类
在realizeClassWithoutSwift方法出打一个断点,并在控制台输入bt打印一下堆栈,就会发现在消息第一次调用时,进行加载

懒加载类与非懒加载分类
在attachToClass处打个断点,查看ro的内容,就会发现methodlist中的个数是8个,说明类加载了

继续向下执行就会发现执行attachCategories方法,开始加载分类

主类懒加载,分类为非懒加载,那么就会迫使主类提前加载 。
非懒加载类与懒加载分类
非懒加载类与两个懒加载分类
LGPerson实现load方法,两个分类不实现load方法
在realizeClassWithoutSwift方法中打个断点,查看ro发现methodList的个数有16(主类有两个属性和四个方法,每个分类都有四个方法)个,只在data()中读取,并只处理一下相同方法名的函数。
总结:

网友评论