一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
cache 在什么时候开始扩容 , 为什么?
- 1、一般情况下:如果当前方法 cache 之后,缓存的使用容量会超过总容量的 3/4,那么,此时就不会先插入,而是先触发扩容,扩容为原来的 2 倍,然后再插入本次的方法;
- 2、某些特殊预处理宏定义编译命令下,首次会存储满之后再开始扩容;
- 3、扩容时选用 3/4 作为负载因子是和 hash 表底层使用的链表以及红黑树的数据结构有关,0.75是最符合泊松分布概率计算得出的数值,在这个数值下哈希表的空间和时间效率都是最高的。
objc_msgSend 为什么用汇编写 , objc_msgSend 是如何递归找到 imp?
- 1、使用汇编响应速度快;
- 2、这个过程中使用了两个循环:
- 1、循环 1:通过前面获取的
mask
,与要查找的_cmd
进行hash
运算,获取下标,从而得到_cmd
对应的 bucket 地址,然后进行向前平移查找,每次平移 16 个字节,如果找到对应的 sel,则cacheHit
;当平移到buckets
的首地址,依然没有查找到,则进入第二个循环; - 2、循环 2:首先会获取末尾
bucket
的地址,同样采用向前查找的方式,向_cmd
对应的地址进行平移查找。
- 1、循环 1:通过前面获取的
一个类的类方法没有实现为什么可以调用 NSObject 同名对象方法?
这里涉及到 isa 和 superclass 的走位以及方法查找逻辑。
首先类的 isa 指向元类,在方法快速查找时,会根据类的 isa
找到元类,元类中没有该方法,就会走到 lookUpImpOrForward
慢速查找流程中。在慢速查找流程中,会进行 for
递归查找,根据 superclass
查找到元类的父类,也就是根元类,而根元类的 superclass
指向了 NSObject
,所以会调用到 NSObject
的同名对象方法。
objc 对象的 isa 的指针指向什么?有什么作用?
指向他的类对象,从而可以找到对象上的方法 \
详解:下图很好的描述了对象,类,元类之间的关系:
图中实线是 super_class 指针,虚线是 isa 指针。注意⚠️:此图很重要,请反复理解查看。
- 1.Root class (class)其实就是 NSObject,NSObject 是没有超类的,所以 Root class(class)的 superclass 指向 nil。
- 2.每个 Class 都有一个 isa 指针指向唯一的 Meta class\
- 3.Root class(meta)的 superclass 指向 Root class(class),也就是 NSObject,形成一个回路。\
- 4.每个 Meta class 的 isa 指针都指向 Root class (meta)。