Objective-C - runtime 之 Class 和 Meta Class

Objective-C Runtime源码

类的定义

我们知道一个类的类型为 Class,

Class class = [self class];

Class class = NSClassFromString(@"class_name");

即 Class 是一个数据类型,那么 Class 是怎么定义的呢?


objc.h文件中有Class的定义:

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

可以看出Class是一个指向结构体objc_class的指针。


runtime.h中可以看到objc_class的结构:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
};

即:

struct objc_class {
    struct objc_class;
}

由此我们可以知道,Class的定义是一个递归定义,它包含一个 isa 指针,指向它所属的类型。

类的结构

objc-runtime-new.hobjc_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();
    }

    ...
    ...
};


在上面objc-class的结构中,data() 方法调的是 bits 的 data() 方法,返回值类型为 class_rw_t,它是一个结构体,结构体定义放在objc-runtime-new.h中:

struct class_rw_t {
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;

    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;

    ...
};
其中
methods中保存了该类定义的成员方法;
properties中保存了该类的所有属性。
protocols中保存了该类遵从的协议。

另外,可以看到还有一个类型为 class_ro_t的ro成员,class_ro_t 也是定义在这个文件中的,结构如下:

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

其中的 ivars 就是用来存放成员变量的,包括定义属性的时候,自动生成的 ivars。

对象

对象是类的一个实例,对象的代码实现也是一个结构体, objc_object,定义在 objc.h 中,结构如下:

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

对象有一个isa指针,指向它所属的类。

Meta Class

从上面可以知道,每一个对象都有一个isa指针指向它所属的类,这个类描述了对象的数据格式:为对象分配的空间大小、成员变量的类型及布局,还有对象的行为,即它能够响应的方法。

在 Objective-C 的设计哲学中,一切皆对象,类也不例外。Class 本身也是一个对象,而这个 Class 对象的对应的类,我们叫它 Meta Class。即 Class 结构体中的 isa 指向的就是它的 Meta Class。

Meta class 是类的描述,就像类是普通对象的描述一样。Meta Class中的方法列表是类方法。当你向类发送一个消息,即调用一个类方法的时候,objc_msgSend()在 Meta Class 方法列表中查找来决定调用哪个方法。

当然,Meta Class 也有一个 isa 指针,指向它所属的类。Meta Class 是根类(root class)的实例,root class 的 isa 指针指向 root class 自身,即 root class 本身既是一个 class,也是一个 meta class。

用一张图来描述对象、类、与 Meta Class之间的关系:
来自 Greg Parker

References

  1. Apple开源的Runtime源码
  2. What is a meta-class in Objective-C? - Matt Gallagher - Cocoa with Love
  3. [objc explain]: Classes and metaclasses - Greg Parker
  4. 刨根问底Objective-C Runtime
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值