文章部分出于自己的理解,有不对的地方,希望大家指正。
实例对象我们可以看作是一个指针,实例对象通过isa指针指向类对象,类对象通过isa指针指向元类对象,类对象和元类对象本身其实都是objc_class结构体,里面存放着我们需要的方法列表等。
那么当我们方法调用的时候,方法是如何缓存的呢?
当我们方法调用的时候,首先通过isa指针找到类对象,然后在类对象的方法列表里面查找相对应的方法,找到以后会加入到我们方法缓存里面,等下次我们再调用的时候,首先会先从缓存里面去查找相关方法,更加的效率。
那如果我们调用的是父类里面的方法呢,其实父类对象里面的方法是不可以缓存到子类方法缓存列表里面的,所以,当我们调用的是父类对象里面的方法的时候,其方法不会在子类对象方法缓存列表里面进行缓存。
元类对象的相关缓存同类对象。
至于缓存扩容和具体的缓存策略:
在arm64结构,也就是真机环境下,刚开始初始化的缓存方法的容器的长度2,当容器的长度小于8时,是满容量了才扩容。当容器的长度大于8时,是7/8扩容。也就是说当容器的长度为8时,容器可以存储8个方法。当容器的长度为16时,当第15个方法需要存储进来的时候,容器就要扩容了。
在x86_64架构下,刚开始初始化的容器的长度为4,是3/4扩容。这里的3/4扩容指的是:如果容器的长度为4,当第3个数据需要存储的时候,就要扩容了。如果容器的长度为8,当第6个数据需要存储的时候,就要扩容了。也就是说容器只能存储容器长度的3/4减1个方法。
还有一点就是:当容器扩容之后,前面存储的方法也会随之清空。