ios底层原理

ios底层核心模板结构 - list_array_tt & en

2022-07-05  本文已影响0人  erlich

探索objc底层原理过程中,经常会碰到一个模板 list_array_tt

你在类加载,方法查找,散列表,同步锁等等都会碰到这个结构,c++的模板功能十分强大,但代码看上去确实比较头疼

其实没那么糟了,我们可以尝试了解下这个结构,对探索ios底层源码很有帮助,如果不以模板的角度去考虑,那么在分析源码的过程中,很多逻辑就会想淡然,底层的理解上就会止步不前

初步预览 list_array_tt

image.png

list_array_tt 是个模板,存在于runtime头文件中,可见它对于runtime api的重要性了

最简单粗俗理解,从模板命名看,List Element,逻辑上就是一个容器List 与 元素Element的关系,不过不是简单的线性关系

image.png

list_array_tt 鸟瞰结构

list_array_tt 关键方法整理

预览 entsize_list_tt

image.png

entsize_list_tt 也是个模板,也存在于runtime 头文件中

image.png

entsize_list_tt 鸟瞰结构

entsize_list_tt 关键方法整理

此处发现有个迭代器,list_array_tt也有个迭代器,会感觉烦乱,后面我会拆解

entsize_list_tt 迭代分析

迭代器iterator是个内部结构体 内部结构

迭代器iterator的迭代功能其实很简单,主要通过运算符号重载实现迭代器的 ++ -- *取元素 ->取元素指针 ==判断元素相等 != > < 比较大小

operator 重载符号 是c++的重载运算符的语法,就是把运算符重载为迭代器的函数,运算符当作函数,通过传惨调用函数 实现迭代过程中的运算逻辑

image.png

自增1 自减1 都是通过迭代器当前元素指针偏移 指针节点个数来实现的,可以对照链表偏移节点那样去理解 但你再仔细看下,这是内存偏移

可以简单猜测一下 此处的迭代器 在 list_array_tt中也会使用到,先不用考虑list_array_tt中的迭代器结构,从鸟瞰代码预览中,大致已经知道 list_array_tt 是个两层嵌套结构

list_array_tt 双层嵌套结构

回到 list_array_tt

list_array_tt 中的迭代器分析

image.png

可能会有人觉得这个List::iterator 理解起来有点困难

其实这个List就是模板 entsize_list_tt ,这么说可能还是有点迷糊 举个实例或许比较容易理解一些

image.png

objc类的底层结构 method_array_t property_array_t protocol_array_t 都是继承自list_array_t

而且 这几个数据结构 都采用了一样的模板结构,不管是叫 method_list_t, property_list_t, 还是 protocol_list_t

image.png

在 list_array_tt 中 都对应了 模板List,元素都是Element

我们再分别看下 method_list_t, property_list_t 这几个模板具体定义

image.png image.png image.png

不管 method_list_t, property_list_t 的名字怎么起,最终都是继承自 entsize_list_tt模板结构而来, 就是模板容器List

上面的例子稍微总结下

试着多想想,发散开了想,既然runtime中这么多的复用这个结构,自然这个结构很重要了,其实不只iOS底层了,其他很多语言都有这样的类似结构

c++本身就是跨平台的,而你也许听过了解c++,就必须深入了解它的模板机制

好了 回归到上面的 list_array_tt 迭代器,在这个迭代器里,出现了 List::iterator

image.png

这是 list_array_tt 中的迭代器

Ptr就是模板List的指针封装而已,就是List的begin end函数,也就是 entsize_list_tt中的迭代器 begin end函数

至此 前面的关于 外层迭代器调用 内层迭代器的猜想得证

list_array_tt 中的迭代器操作理解

list_array_tt 中成员array_t 与 list理解

list_array_tt - attachLists流程分析

到这儿就是这篇文章最核心的内容了,但是没有前面的铺垫,这块没法阐述

为什么重要,如果要了解ios类的加载流程,这个attachLists流程你肯定绕不过去,不然你没办法理解 rwe 以及分类的加载逻辑 那这块的认知始终会处于坍缩状态

void attachLists(List* const * addedLists, uint32_t addedCount)

上一篇 下一篇

猜你喜欢

热点阅读