Runtime笔记(二)—— Class结构的深入分析


Runtime系列文章

Runtime笔记(一)—— isa的深入体会(苹果对isa的优化)
Runtime笔记(二)—— Class结构的深入分析
Runtime笔记(三)—— OC Class的方法缓存cache_t
Runtime笔记(四)—— 刨根问底消息机制
Runtime笔记(五)—— super的本质
[Runtime笔记(六)—— Runtime的应用…待续]-()
[Runtime笔记(七)—— Runtime的API…待续]-()
Runtime笔记(八)—— 记一道变态的runtime面试题

我在OC对象的本质(下)—— 详解isa&superclass指针中,有介绍过Class对象的内存结构,如下图实例对象、类对象、元类对象的内存布局
本文就以此为起点,来仔细挖掘一下Class内部都有哪些宝贝。


(一)Class的结构简述

首先我们来看一下objc源码对Class的定义

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);
    }
     //......下面的一堆方法/函数代码可以暂时不用关注
};

结构比较清晰

  • Class superclass;——用于获取父类,也就是元类对象,它也是一个Class类型
  • cache_t cache;——是方法缓存
  • class_data_bits_t bits;——用于获取类的具体信息,看到bits,想必看过我写的Runtime之isa的深入体会(苹果对isa的优化)这篇文章,一定会深有体会。
  • 紧接着有一个class_rw_t *data()函数,该函数的作用就是获取该类的可读写信息,通过class_data_bits_tbits.data()方法获得,点进该方法看一下
class_rw_t* data() {
   
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }

可以看到,跟我们之前通过isa获取对象地址操作很像,这里是将类对象里面的class_data_bits_t bits;和一个FAST_DATA_MASK进行&运算取得。返回的是一个指针,类型为class_rw_t *,查看该类型的源码如下

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;
}

我们知道,OC类的方法、属性、协议都是可以动态添加,也就是可读可写的,从上面的源码中,可以发现确实是有对应的成员来保存方法、属性、协议的信息。而从该结构体的名字class_rw_t,也暗含了上述的方法、属性、协议信息,是可读可写的。另外,我们知道Class类里面的成员变量是不可以动态添加的,也就是属于只读内容,相应的,可以推断const class_ro_t *ro;就是指向了该部分内容信息的指针。同样,查看其源码

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;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值