objc_setAssociatedObject 关联对象存在哪里
status
category
date
summary
slug
icon
tags
password
实现某个功能时,使用 objc_setAssociatedObject 添加了一个关联对象,于是好奇关联对象存在哪里,在此探索并记录。本文只关注关联对象的存储形式,没有对存、取、删的过程和逻辑做详细分析。
版本:objc4-781
主要文件:
objc-references.mm
关联对象的使用
objc runtime 提供了三个运行时方法:
三个方法的作用分别是:
- 为 object 添加一个关联属性 value,并指定了 key 和 policy
- 获取 object 的 key 对应的关联对象
- 移除 object 所有的关联对象
关联对象的存储,首先认识一下这个方法中用到的数据结构。
AssociationsManager
它本身是一个单例,且维护了一个 spinlock_t 和 AssociationsHashMap 的单例。
AssociationsHashMap
AssociationsHashMap 完成了 DisguisedPtr 到 ObjectAssociationMap 的映射。
DisguisedPtr
DisguisedPtr 对一个指针做伪装处理,保存时装箱,调用时拆箱,DisguisedPtr 在功能上等价于 T*.这样做的目的是将储存值隐藏起来,不让 leaks 之类的内存检测工具看到。
ObjectAssociationMap
ObjectAssociationMap 完成了对象指针到 ObjcAssociation 的映射。
ObjectAssociation
ObjcAssociation 是真正的关联对象类,上面的数据结构都是为了储存它。
ObjcAssociation 保存了需要被关联的对象和对应的内存管理模式
objc_AssociationPolicy
相当于 property 需要声明的内存管理模式
总结
如果要给 object 添加一个关联对象 value,简单来说,runtime 维护了一张全局的哈希表,以 object 为 key,对应的值为 ObjectAssociation,包含了内存管理策略 policy 和关联对象 value。那么可以联想,关联对象的获取、替换、删除操作,也都是对这个哈希表的操作。
(此处立一个 flag,等 iPad 到货之后手绘一下上述结构的关系图。)
这是我看源码最快也是最简单的一次,没有探究 objc_setAssociatedObject 方法内部的具体逻辑,只是记录了一些数据结构。因为我确实是只对关联对象的存储形式感到好奇,这样不求甚解也足以高效地解答我的疑惑。
Loading...