美文网首页
ios-关联对象

ios-关联对象

作者: erlich | 来源:发表于2022-08-13 01:50 被阅读0次

    关联对象常见的一种做法

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

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

    get里使用 objc_getAssociatedObject

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

    找源码

    image.png image.png

    出现了两个关键变量

    image.png

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

    image.png

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

    又出现了两个变量

    image.png

    AssociationsManager

    image.png
    image.png
    image.png

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

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

    AssociationsHashMap结构

    image.png

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

    image.png image.png image.png

    查找的过程是这样

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

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

    bucket->getFirst() ---- key

    bucket->getSecond() ---- Value

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

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

    调试 AssociationsHashMap

    image.png image.png image.png image.png image.png image.png

    再看AssociationsHashMap 结构

    • Buckets

    • NumEntries

    • NumTombstones

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

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

    直观结构

    image.png

    假设对象 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}

    相关文章

      网友评论

          本文标题:ios-关联对象

          本文链接:https://www.haomeiwen.com/subject/iblfgrtx.html