美文网首页
OC中的class和meta-class对象的结构分析

OC中的class和meta-class对象的结构分析

作者: it小小菜鸟 | 来源:发表于2020-07-10 17:43 被阅读0次

class和meta-class对象的类型都是 struct objc_class 结构体

struct objc_class 结构分析

  • 在源码中的部分代码如下:源码版本:objc4-
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 *data() const {
        return bits.data();
    }
    ...

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

从上面可以看出 struct objc_class 的内存结构可以理解为:

struct objc_class {
    Class isa;
    Class superclass;
    cache_t cache;             // 方法缓存
    class_data_bits_t bits;  // 用于获取具体的类信息
};
  • 通过bits获取类信息
class_rw_t *data() const {
        return bits.data();
    }

通过上面这个方法,可以得到一个可读写信息表:

struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint16_t witness;
#if SUPPORT_INDEXED_ISA
    uint16_t index;
#endif

    explicit_atomic<uintptr_t> ro_or_rw_ext;

    Class firstSubclass;
    Class nextSiblingClass;
    // 获取只读信息表
    const class_ro_t *ro() const {
        auto v = get_ro_or_rwe();
        if (slowpath(v.is<class_rw_ext_t *>())) {
            return v.get<class_rw_ext_t *>()->ro;
        }
        return v.get<const class_ro_t *>();
    }
    // 获取方法列表
    const method_array_t methods() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>()->methods;
        } else {
            return method_array_t{v.get<const class_ro_t *>()->baseMethods()};
        }
    }
    // 获取属性列表
    const property_array_t properties() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>()->properties;
        } else {
            return property_array_t{v.get<const class_ro_t *>()->baseProperties};
        }
    }
    // 获取协议列表
    const protocol_array_t protocols() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>()->protocols;
        } else {
            return protocol_array_t{v.get<const class_ro_t *>()->baseProtocols};
        }
    }

class_ro_t 只读信息表部分源码如下:

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize; // instance对象占用的内存空间
#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;
  • 大致关系可以表示如下图:
    截屏2020-07-10 下午5.35.08.png

相关文章

网友评论

      本文标题:OC中的class和meta-class对象的结构分析

      本文链接:https://www.haomeiwen.com/subject/gmimcktx.html