ios底层原理

ios-散列表

2022-08-11  本文已影响0人  erlich

ios 引用计数 retain release过程中不免要操作一张散列表(taggedPoint 也不在此次讨论范围内)

那么散列表究竟是个什么样的结构,它与引用计数的关系是什么样的,这是我们此次通过源码探究的主题

进入libobjc 源码 (具体源码参考 - objc4-841.13可调试/编译源码更新(for M1))

以retain为例 涉及到一个结构

image.png image.png

引出StripedMap

image.png

StripedMap 中包含一个数组,数组个数 -- arm 8; x86-64 64

以arm为例,就是 StripedMap中存储了8张表

image.png

我们具体操作的时候 是取StripedMap 中的某一张表

取表的过程

由于 StripedMap 是全局的,必然存在访问问题,表中的元素 加锁 解锁操作

image.png

上面最开始的retain示例中,SideTables(), 就是获取到了 StripedMap

SideTables()[this] 就是 StripedMap[对象指针], 上面已提到过运算符[]重载

SideTable

image.png

你会发现操作这两表时 为了线程安全,避免不了锁的操作,必然存在性能消耗与效率问题

既然 表是全局的,必然存在回收机制

以refcnts为例, 拿到 SideTable之后,进一步 取RefcountMap

StripedMap[对象指针].refcnts ---> RefcountMap

image.png

其实 RefcountMap 为了安全考虑,掩盖了指针

继续向上溯源 objc::DenseMap

image.png

继续 DenseMapBase

image.png image.png

又又出现了 运算符[]重载

理解散列表

对于散列表的理解,需要自带一些抽象气质

image.png
image.png

引用计数表 - 引用计数逻辑

引用计数的操作主要包含两部分 retain / release

上一篇下一篇

猜你喜欢

热点阅读