返回

深入浅出剖析OC方法的本质(下)

IOS

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结构体的访问速度,runtimeclass_rw_t结构体进行了优化。优化后的class_rw_t结构体如下:

struct class_rw_t {
    uint32_t    flags;
    uint32_t    version;
    uintptr_t    ro;
};

可以看到,优化后的class_rw_t结构体中,flagsversion字段的类型都从uintptr_t变为了uint32_t。这主要是考虑到flagsversion字段通常都是较小的整数,使用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方法的本质有更深入的理解。