本篇英文名叫 CWC:Kitchen Tools That Cook Loves ,翻译过来的意思是 苹果源码中出现的一些数据结构 ,不断积累更新。
CWC : Cooking With Cook ,翻译过来的中文意思就是 作为一个长期热爱苹果的苹果开发者,我们要陪着水果公司一起积累和成长。
目前: entsize_list_tt 、 list_array_tt 、 cache_t's buckets ...
entsize_list_tt 其实就是一个通用的容器,可以获取 内部的迭代器,用于遍历内部存储的元素
出现场景:
三者的声明头如下:
entsize_list_t 定义源码,省略大部分方法:
这个类用来表示一个空、单数组、或者多数组。它和 list 的区别就是 多了一个多维数组的封装。
出现场景:
ro 中没有,只有三个单 List。
三者的声明头如下:
list_array_tt 源码部分如下:
cache_t 的结构体定义:
buckets 的内部是一个连续的存储空间,存储是一个散列表。
开辟声明的函数调用的是 calloc
当 msgSend 的时候,就会调用 fillCache 进行方法的缓存,存储的涉及 cls sel 和 imp
bucket_t 的结构体很有意思,arm64 和 i386 的两个值的顺序是反着的。
arm64 的时候是 :
armv7* , i386 和 x86_64 的时候是:
源码注释:
初始的 capacity 是 4。
源码中 cache_t::insert(cls, sel, imp, reveiver) 方法调用的时候,判断扩容。
fastpath(newOccupied + CACHE_END_MARKER <= capacity / 4 * 3)
也就是说当大于四分之三的时候,就会进行扩容 *** 作,每次 double 扩容
capacity = capacity ? capacity * 2 : INIT_CACHE_SIZE
当然不是无限制的扩容,有一个最大容量的限制:
MAX_CACHE_SIZE = 1 <<16
这个类型应该是执行最多次的,看一些文章说一秒钟iOS中执行几百万次
explicit_atomic用来给catchT缓存方法用,核心是原子性和线程安全。
weak弱引用的散列表
扩展: non-fragile structs 是什么?OC 1.0 (iOS自始至终都是2.0起的,Mac最开始是1.0)译器生成了一个 ivar 布局,显示了在类中从哪可以访问 ivars ,对 ivar 的访问就可以通过 对象地址 + ivar偏移字节 的方法。苹果更新了NSObject类,例如增加一些属性,这个又是静态库,发布新版本的系统,这个时候布局就出错了,就不得不重新编译子类来恢复兼容性。(那如果是在线上运行的app,升级系统后就没办法运行了)
使用 Non Fragile ivars 时,程序进行检测来调整类中新增的 ivar 的偏移量。 这样就可以通过 对象地址 + 基类大小 + ivar偏移字节 的方法来计算出 ivar 相应的地址,并访问到相应的 ivar。(即使升级iOS系统,之前的app也能正常运行)
扩展再扩展: 为什么OC类不能动态添加成员变量? runtime函数中,确实有一个class_addIvar()函数用于给类添加成员变量,但是文档中特别说明: This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported. 这个函数只能在“构建一个类的过程中”调用。一旦完成类定义,就不能再添加成员变量了。经过编译的类在程序启动后就被runtime加载,没有机会调用addIvar。程序在运行时动态构建的类需要在调用objc_registerClassPair之后才可以被使用,同样没有机会再添加成员变量。
理论上说,我还是认为可以添加,只是为什么一定不可以,就不得而知了。
deb文件是一种Debian Linux发行版的安装文件,可以用来安装应用程序,但是不能用来查看源码。要查看源码,需要从苹果开发者网站下载Xcode,Xcode是一款开发环境,可以查看和编辑源代码,它也可以用来编译和打包应用程序。此外,还可以通过第三方工具,如Github、Gitlab等,来获取源代码。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)