ios-关联对象

关联对象常见的一种做法

在分类里想增加属性,由于只会生成 set get方法,并不会存在 属性与成员

这个时候的做法往往是 在set 里 调用objc_setAssociatedObject

get里使用 objc_getAssociatedObject

那么 关联对象究竟如何实现,这是本次探究的主题

找源码

在这里插入图片描述

在这里插入图片描述

出现了两个关键变量

在这里插入图片描述

关于 DisguisedPtr<objc_object> ,可以对比另一篇博客 ios-弱引用 里提到的结构,顺便了解一下 它是怎么用的

在这里插入图片描述

ObjcAssociation 里 value的访问类似于 我们常规的property retain copy的修饰

又出现了两个变量

在这里插入图片描述

AssociationsManager

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可能你会没什么感觉,太抽象的代码,没关系,你也可以忽略,因为 全局变量 不是靠我们程序员初始化的,libc 会在c++初始化器运行之前就调用了

只需要知道 AssociationsManager get() 可以获取到全局的 AssociationsHashMap

AssociationsHashMap结构

在这里插入图片描述

为了对 AssociationsHashMap 结构更有感知,直接通过它的使用是最好的方式

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查找的过程是这样

hash(objc伪装地址) --> 得出 index,也就是buckets起始位置偏移索引index

buckets 首地址 + index --> 得到bucket

bucket->getFirst() ---- key

bucket->getSecond() ---- Value

首次 通过 hash 得到 bucket,比较 bucket->getFirst() 与 disguisedPointer (也就是伪装地址) 是否相等

如果不匹配,则顺序挨个遍历查找

调试 AssociationsHashMap

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

再看AssociationsHashMap 结构

  • Buckets

  • NumEntries

  • NumTombstones

  • NumBuckets ------- 数量为4 后续会存在扩容逻辑

从这层开始,第一步 就是 根据 hash(objc) 找 Buckets 的哪一个, 第一次可能命中 bucket,也可能没找到,也可能冲突,总之没找到,就去遍历查找

直观结构

在这里插入图片描述

假设对象 objc, 属性 key 属性值 value

  • objc 求hash ==> index
  • buckets[index] ==> bucket
  • bucket->second ==> sub_buckets (bucke->first ==> objc)
  • key 求hash ==> sub_index
  • sub_buckets[sub_index] ==> sub_bucket
  • sub_bucket->second ==> association. (sub_bucket->first ==> key)
  • association ==> {policy, value}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值