1.Category底层结构,如下
2.使用指令从编译后的c++代码,也可以看出是把在分类中写的方法都赋值给了结构体
将Objective-C代码转换为C\C++代码
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件
如果需要链接其他框架,使用-framework参数。比如-framework UIKit
第一张图中圈的值赋值给了第二张的结构体属性里。
3.分析Category怎么把方法合并到类中的。
是通过dyld装载程序,初始化runtime环境的时候加载到类对象里
直到最后调用到如下方法
上图中圈中2行代码做的事情就是把分类的方法列表加到原始类的方法列表前面。
所以最终会导致,对象调用方法时,先找到分类的方法进行调用。
也就是我们常说的分类方法会“覆盖”原来类的方法的现象,但实际上并不是覆盖,而是因为分类方法被添加在了前面。
因为消息机制isa在查找方法的时候找到就直接调用了,后面不会再管了。
4.我们所写的就分类的方法,如果重名的话,会由编译顺序决定调用哪一个。
还有一点要注意就是写静态库里other linker flags 设置成 -all_load。
5.+load方法的调用
也是在dyld装载程序,初始化runtime环境的时候调用的。所以代码不管是否使用就会调用。
最后调用
而且两个方法内部调用都是直接方法调用,没有使用objc消息机制。
所以写了原类,子类,分类.三个类里面的+load都会依次调用。
6.+initialize方法, 首次使用类的时候只会调用一次
可以看到方法调用采取的是objc消息机制调用,
所以结果为
比如写了原类,子类,分类.三个类里面的+initialize方法,只有原类、分类依次调用。
5和6的调用结果如下图
PS:介于时间有限,本篇只列了一些重点并不算是详细,