class_ro_t 和 class_rw_t 区别
细看两个结构体的成员变量会发现很多相同的地方,他们都存放着当前类的属性、实例变量、方法、协议等等。
区别在于:class_ro_t存放的是编译期间就确定的;
而class_rw_t是在runtime时才确定,它会先将class_ro_t的内容拷贝过去,然后再将当前类的分类的这些属性、方法等拷贝到其中。
所以可以说class_rw_t是class_ro_t的超集,当然实际访问类的方法、属性等也都是访问的class_rw_t中的内容
iOS 类数据结构
class_rw_t
class_rw_t里面的methods、properties、protocols是二维数组,是可读可写的,包含了类的初始内容、分类的内容
class_ro_t
class_ro_t里面的baseMethodList、baseProtocols、ivars、baseProperties是一维数组,是只读的,包含了类的初始内容
method_t
方法缓存
Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高方法的查找速度
缓存查找
在objc源码的objc-cache.mm文件内
方法bucket_t * cache_t::find(cache_key_t k, id receiver)
区别
在class_ro_t结构体中,也定义了方法列表、协议列表、属性列表、变量列表。class_ro_t中的方法列表和class_rw_t中的方法列表有什么区别呢?
实际上,class_ro_t结构体存储了类在编译期间确定的属性、方法、协议以及变量。解释一下,Objective-C是动态语言,因此Objective-C的运行需要编译期和运行时系统共同合作,这一点在类的方法的体现的非常明显。
Objective-C代码经过编译之后,会生成类结构,以及根据代码生成类的属性、方法、协议、变量,这些信息在编译期间就能够完全确定,编译期间确定的信息保存在class_ro_t结构体中。因为是在编译期间确定的,所以是只读的,不可修改,ro,代表readonly。在运行时,可以往类结构中增加一些额外的方法、协议,比如在Category中写的方法,Category中的方法就是在运行时加入到类结构中的。运行时生成的类的方法、属性、协议保存在class_rw_t结构体中,rw,代表readwrite,可以修改。