Category原理

327 阅读2分钟

前几天面试问到分类的加载,面试官很nice,帮我指出了错误,但是人家只是很谦卑的说:我们对这的实现细节可能有分歧,也许是runtime源码版本不一致。真的是谦虚!人也和蔼的指出了我的不足,还指导了别的东西。真希望跟这样的人共事!他说的是分类方法是前插进rw里。我一直误以为是倒序遍历方法列表查找的。。。所以翻出来源码,再看看。 runtime-723版本

以上是category的结构体,里面压根没有ivar这个东西,所以也就是添加不了成员变量。其他的,实例方法,类方法,协议,实例属性都是可以添加的,但是需要我们自己实现set,get方法

以上是id类型结构体,id可以转换成任何类

objc_class是继承自objc_object结构体的。这个结构体里面有superClass,方法缓存,data_bit的结构体,这个结构体里包含一个class_rw_t的结构体,分类方法等就是插入到这个结构体里

class_rw_t的结构体里又包含了class_ro_t的结构体,readOnly的,不可读写,就是类原本的一些结构。

可以看到ro这个结构体里才有ivars,就是成员变量了

程序启动的时候,dyld把可执行文件加载进来,然后runtime接管,解析可执行文件,就到了这一步,这个是mac-os的文件里,点进map_images继续看,发现到了runtime的文件下,下面就是runtime加载类信息。镜像加载进来,当然要读取镜像,找到readImage的方法

然后你会发现Discover categories,就是分类相关的了。顺着一步步跳,会找到attach(附加)分类的方法

源码里做了注释,也给自己提醒。走马观花的看,并不是真的看,还会造成误解! 贴出来,提醒自己,记住这个,也记住那位nice的面试官!