深入浅出剖析OC方法的本质(下)
2023-10-17 11:30:07
class_rw_t
的优化
在上一篇文章中,我们提到class_rw_t
结构体用于存储类的信息,包括方法表、成员变量表等。class_rw_t
的结构如下:
struct class_rw_t {
ptrdiff_t flags;
uintptr_t version;
uintptr_t ro;
};
其中,flags
字段用于存储类的标志信息,如是否为final
类、是否为abstract
类等;version
字段用于存储类的版本号,用于判断类的二进制兼容性;ro
字段用于存储类的只读数据,如类名、父类名等。
为了提高class_rw_t
结构体的访问速度,runtime
对class_rw_t
结构体进行了优化。优化后的class_rw_t
结构体如下:
struct class_rw_t {
uint32_t flags;
uint32_t version;
uintptr_t ro;
};
可以看到,优化后的class_rw_t
结构体中,flags
和version
字段的类型都从uintptr_t
变为了uint32_t
。这主要是考虑到flags
和version
字段通常都是较小的整数,使用uint32_t
类型可以节省空间。
实例方法和类方法的存储位置
实例方法和类方法都是方法,但它们存储在不同的位置。实例方法存储在类
中,而类方法存储在元类
中。
元类
是一个特殊的类,它是类的类
。元类
存储着类的信息,如类名、父类名、方法表、成员变量表等。元类
的class_rw_t
结构体与类的class_rw_t
结构体是相同的。
实例方法和类方法的区别在于:
- 实例方法只能被类的实例调用,而类方法可以被类的实例和类本身调用。
- 实例方法存储在
类
的方法表
中,而类方法存储在元类
的方法表
中。
copy
属性的实现方式
copy
属性是一种特殊的属性,它可以使属性的值在对象之间进行复制。copy
属性的实现方式是使用objc_setProperty
函数。
objc_setProperty
函数的原型如下:
void objc_setProperty(id obj, SEL name, id value, BOOL atomic);
其中,obj
是对象,name
是属性名,value
是属性值,atomic
表示是否使用原子操作。
当使用copy
修饰属性时,runtime
会自动生成一个名为_name
的私有成员变量来存储属性的值。当对象收到setName:
消息时,runtime
会使用objc_setProperty
函数将属性值复制到_name
私有成员变量中。
总结
本文深入探讨了class_rw_t
的优化,实例方法和类方法的存储位置,以及copy
属性的实现方式。通过剖析这些细节,希望读者能够对OC方法的本质有更深入的理解。