objc_class的内部结构

1、objc_class内部结构

NSObject对象的数据结构都是存储在objc_class内部的,即objc_class有什么,NSObject以及 我们继承后自定义的对象就有什么

// objc_class继承自objc_object,所以会有一个属性isa
struct objc_class : objc_object {
    // Class ISA;
    Class superclass; // 指向父类的地址
    cache_t cache;   // 方法缓存列表
    //结构体,内部存储着主要的数据,通过&不同的掩码值获取不同的信息地址
    class_data_bits_t bits;  
    // 获取存放在bits中的可读可写的数据信息
    class_rw_t *data() { 
        return bits.data();
    }
   ......
}

objc_class的主要信息都隐藏在bits中,那么返回后的class_rw_t中存放的是什么呢?

struct class_rw_t {
    uint32_t flags;
    uint32_t version;
  
    const class_ro_t *ro;  // 只读的,Class的初始信息
    method_array_t methods; // 方法列表
    property_array_t properties; // 属性列表
    protocol_array_t protocols; // 协议列表

    Class firstSubclass;
    Class nextSiblingClass;
    char *demangledName;
}

rw_t: read write table 可读可写,说明,后期我们可以向里面添加信息
class_ro_t:read only table 创建类的时候的初始信息

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; // 初始属性列表
    ......
}

注意:
class_ro_t中的列表都是list_t
class_rw_t中的列表都是array_t,而且class_ro_t中多了一个ivars成员变量列表

思考:
1.class_ro_t 与class_rw_t 之间有什么联系
2.array 与list 有什么区别和联系

2、method_array_t 与 method_list_t

method_array_t里面存放的是 method_list_t数组,所以method_array_t是一个二维数组
method_list_t里面存放是的metod_t 是一维数组

//举例说明 array_t 和list_t的关系
class method_array_t : 
// C++的语法,是一种泛型,
// method_array_t里面存放的是method_list_t, 二维数组
//method_list_t 里面存放的是method_t ,一维数组
    public list_array_tt 
{
    typedef list_array_tt Super;
 public:
    method_list_t **beginCategoryMethodLists() {
        return beginLists();
    }
    
    method_list_t **endCategoryMethodLists(Class cls);

    method_array_t duplicate() {
        return Super::duplicate();
    }
};

同理,property_array_t和protocol_array_t也是存放的对应类型的二维数组

3、method_t

struct method_t {
    SEL name; // 方法选择器,也就是方法的名字
    const char *types; // 方法的返回类型和参数
    MethodListIMP imp; // 方法的存放地址
};

4、总结

1.objc_class内部包含superclass、cache方法缓存列表,bits类的信息
2.bits & 一个掩码值才能获取到内部的数据
3.class_rw_t 是可读可写的,目的是方便以后可以向里面插入新的数据,如分类,在程序运行的时候,会将分类和class_ro_t中的数据按顺序挪放到class_rw_t中,最终可以达到后编译的类方法可以覆盖先编译的类方法
4.class_ro_t 是只读的 ,里面存放的是类的最初的信息
5.method_array_t 是二维数组里面存放的是method_list_t一维数组
6.method_list_t存放的是method_t

你可能感兴趣的:(objc_class的内部结构)