类
类的定义
我们知道一个类的类型为 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.h
中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();
}
...
...
};
在上面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