Category实现的原理一:底层结构及源码分析

Category实现的原理一:底层结构及源码分析,第1张

❓比如说有如下3个类,思考一下如下图所示的实例方法存放在哪里?

下面我们就来验证一下上面的结论.

我们的分类 HHPerson+eat 被转换为类型为 static struct _category_t ,变量名为: _OBJC_$_CATEGORY_HHPerson_$_eat :

实例方法列表:

协议列表: (HHPerson+eat实现了 NSCopying,NSCoding 协议)

属性列表:

以上就是分类的底层结构,可以看到,分类的信息在编译期间都被分离出来了,下面我们从 runtime 源码研究一下分类.

我们梳理一下 attachCategories (cls,cats,true) 方法. attach 一词是 附加 的意思,从名字上我们可以看出这个方法大概意思是: 附加分类 .事实上它的确如此,下面我开始研究:

本篇主要讲了 category 的底层数据结构,和分析 runtime 如何处理 category 分类信息的.在下篇文章中-- Category实现的原理二:分类信息如何添加到本类中 将介绍 runtime 如何将分类信息添加到本类中.

新创建一个命令行项目,创建ZJPerson类和ZJPerson(Study)分类

这样分类就算间接完成添加属性的功能,我们在main函数中使用一下

可以看到分类添加的属性使用效果和在类里直接添加的属性效果一样

我们打开源码,搜索出objc_setAssociatedObject(, 找到这个方法的源码

点击进入_object_set_associative_reference方法

上面这段源码怎么理解呢

大概意思就是有AssociationsManager这么一个类,它的内部维护了一个全局的字典AssociationsHashMap

AssociationsHashMap字典的key对应的是disguised(object),类似于当前对象的内存地址,而value存储的是ObjectAssociationMap字典

ObjectAssociationMap字典的key对应的是添加的属性的名字,value呢,则对应的是ObjcAssociation实例

ObjcAssociation实例则存储着添加属性的值和策略

结构如下图所示

ZJPerson在study分类里添加了一个属性bookName,在main函数中给person实例的bookName属性赋值了@"How to study",那么系统是怎么存储这个属性的值呢?

其存储结构如下

在例如,我们在main函数中创建两个person对象

则其存储结构如下

Category能否添加成员变量?如果可以,如何给Category添加成员变量?


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11446046.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存