前言
oc 方针的本质与isa 和 isa 类的底层原理结构 分别剖析了isa和bits。类里边的成员变量还有superclass和cache,今日就来根究下cache的底层原理。
准备作业
o苹果xbjc4-818.2 源变量与函数码
cache 结构剖析
cache_t
结构图
首要根究cache
的类型cache_t
,源码中查看cache_t
具体类型是结构体指针万用表的使用办法
struct cache_t {
private:
explicit_atomic苹果官网<uintptr_t> _bucketsAndMaybeMask;
union {
struct {
explicit_atomic<mask_t> _maybeMask;
#if __LP64__
uint16_t _flags;
#endif
uint16_t _occupied;
};
explicit_atomi指针数组c<preopt_cache_t *> _originalPreoptCache;
};
/*
#if defined(__arm64__) && __LP64__
#if TARGET_OS_OSX || TARGET_OS_SIMULATOR苹果magsafe电池
// __arm64__的指针的拼音模拟器
#define CACHE_MASK_STORAGE CA源码交易网站源码CHE_MASK_STORAGE_HIGH_16_BIG_ADDRS
#else
//__arm64__的真机
#define CACHE_MASK_源码本钱STORAGE CACHE_MASK_STORAGE_HIGH_16
#endif
#elif defined(__arm64__) && !__LP64__
//32位 真机
#define CACHE_MASK_STORAGE CACHE_MASK指针数学_STORAGE_LOW_4变量
#else
//macOS 模拟器
#define CACHE变量名的命名规矩_MASK_STOR变量值AGE CACHE_MASK_STORAGE_OUTLINED
#endif
****** 中心是不同的架构之间的判别 主要是用来不缓存视频兼并同指针c言语类型 mask 和 buckets 的掩码
*/
public:
voi指针式万用表图片d increm苹果entOccupied();
void setBucketsAndMask(struct b苹果8ucket_t *n指针数组和数组指针的区别e指针式万用表图片wBu指针式万用表图片ckets, m指针万用表的读法ask_t newMask);
void reallocate(mask_指针数组t oldCa苹果官网pacit缓存视频y, mask_t newCapacity, bool fr源码网站eeOld);
unsigned capacity() co缓存是什么意思nst;
struct bucket_t *buckets() const;
Class cls() const;
voi变量泵d insert(SEL sel, IMP imp, id receiver);
// 下面是基本上都是指针c言语其他的办法的办法
};
-
_bucketsAndMaybeMask
变量uintptr_t
占8字节和isa_t中的bits相似,也是一个指针类型里边寄存地址 - 联合体里有一苹果手机个结构体和变量值一个结构体指针
_originalPr源码本钱eoptCache
- 结构体中有三个成员变量
_m源码本钱aybeMask
,_flags
,_occupie缓存的视频怎么保存到本地d
。__LP64__指的是Unix和Unix类体系(Linx和macOS) -
_orig变量是什么意思inalPreoptCache
和结构体是互斥的,_originalPr指针表eoptCache
初始时分的缓存,现在根究类中的缓存,这个变量基本不会用到 -
cache_t
提供了共用的办法去苹果magsafe电池获取值,以及依据不同的架构体系去获取mask和buckets
根究
- 当需求缓存的办法所占的容量总容量3/4是就会直接走缓存流程
- 根究一些变量是什么意思底层源码就会发现,苹果的规划思想,做什么作业都会留苹果官方有地步苹果x。一方面或许为了日后的优化或许扩展,另一方面或变量名的命名规矩许是为了安源码之家全,内存对齐也是这样
- 容量跨越3/4,体系此时会进行两倍扩容,扩容的最大容量不会跨越mask的最大值2^15
- 扩容的时分会进行一步重要的操作,开荒新的内存,开释回收旧的内存,此时的freeOld = true
缓存办法
- 首要拿到bucket()指向开荒这块内缓存视频兼并app下载存首地址,也就是第一个bucket的地址,bucket()既不是数组也不是链表,只是一块连续的内存
- hash函数依据缓存sel和mask,计算出has苹果官方h下标。为什么需求mask呢?mask的实践作用是告知系苹果官方统你只能存前ca变量泵pacity – 1中的方位,比如capacit指针c言语y = 4时,缓存的办法只能存前面3个空位
- 开端缓存,当时的方位没有数据,就缓存该办法。假定该源码之家方位有办法且和你的办法变量名的命名规矩相同,阐明该办法缓存过了,直接return。假定存在hash冲突,下标相同,sel不相同,此时会再次hash,冲突处理继续缓存
insert调用流程
- 调指针式万用表图片用
insert
办法流程:[instance method]
底层完结objc_msgSend --> _objc_msgSend_uncached --> lookUpImpOrForward --> log_and_fill_cache --> cache_t::insert