ObjC 中类的结构体 (objc-runtim-new)

类结构体的定义

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() { 
        return bits.data();
    }
    void setData(class_rw_t *newData) {
        bits.setData(newData);
    }
    ......
};
  • isa 是指向元类的指针,不了解元类的可以看 Classes and Metaclasses
  • super_class 指向当前类的父类
  • cache 用于缓存指针和 vtable,加速方法的调用
  • bits 就是存储类的方法、属性、遵循的协议等信息的地方

class_data_bits_t 其中只含有一个 64 位的 bits 用于存储与类有关的信息。结构体中的注释写到 class_data_bits_t 相当于 class_rw_t 指针加上 rr/alloc 的标志。

它为我们提供了便捷方法用于返回其中的 class_rw_t * 指针:

class_rw_t* data() {
    return (class_rw_t *)(bits & FAST_DATA_MASK);
}

bitsFAST_DATA_MASK 进行位运算,只取其中的 [3, 47] 位转换成 class_rw_t * 返回。

在 x86_64 架构上, Mac OS 只使用了其中的 47 位来为对象分配地址。而且由于地址要按字节在内存中按字节对齐,所以掩码的后三位都是 0 。

因为 class_rw_t * 指针只存于第 [3, 47] 位,所以可以使用最后三位来存储关于当前类的其他信息。

#define FAST_IS_SWIFT           (1UL<<0)
#define FAST_HAS_DEFAULT_RR     (1UL<<1)
#define FAST_REQUIRES_RAW_ISA   (1UL<<2)
#define FAST_DATA_MASK          0x00007ffffffffff8UL
  • isSwift() FAST_IS_SWIFT 用于判断 Swift 类
  • hasDefaultRR() FAST_HAS_DEFAULT_RR 当前类或者父类含有默认的方法
  • requiresRawIsa() FAST_REQUIRES_RAW_ISA 当前类的实例需要 raw isa

class_rw_t

在 objc-runtim-new.h 文件中,源码如下:

struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;

    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;

    Class firstSubclass;
    Class nextSiblingClass;

    char *demangledName;
    ......
};

rw 即 readwrite,内部信息可读可写的。内部包含的信息来源是 runtime 时动态添加的,比如分类中的方法会在运行时添加到method_array_t 中。

class_rw_t 中包括:

  • method_array_t 方法数组
  • property_array_t 属性数组
  • protocol_array_t 协议数组

class_ro_t

在 objc-runtim-new.h 文件中,源码如下:

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
        return baseMethodList;
    }
};

ro 即 readonly 内部信息只读。内部为类编译器生成的信息,不可添加和删除。

class_ro_t 中包括:

  • name 类名
  • method_list_t 方法列表
  • property_list_t 属性列表
  • protocol_list_t 代理列表
  • ivar_list_t 成员变量列表

你可能感兴趣的:(ObjC 中类的结构体 (objc-runtim-new))