深入ObjectiveC Runtime之对象模型

ObjectiveC与C++同样是在C的基础上对C的扩展,但与C++相比,我认为ObjectiveC提供了更加强大的功能,比如Category,forward message, method-swiazzing, KVO以及一些runtime接口,而所有这些技术都是以ObjectiveC强大的Runtime为基础的。因此只有深入学习了runtime的机制,才能使我们对OC的使用更加得心应手, 并且对于大多数runtime技术,我们必须在熟悉它的底层实现机制后才能够达到正确使用的目的,否则的话你将陷入痛苦的debug之中。

对象模型是程序运行时对象在内存中的组织方式,由于ObjectiveC是OOP的编程语言,对象模型就涉及到类的组织方式,继承关系的表示方法成员变量与函数的存储方式如何实现RTTI等,因此对象模型是我们了解ObjectiveC runtime技术实现机制的基础。

###ObjectiveC中对象的数据结构###
我们都知道,ObjectiveC中的大多数类都是NSObject的子类,因此我们先从NSObject的结构开始,在NSObject.h中我们可以看到如下代码:

1
2
3
4
NS_ROOT_CLASS
@interface NSObject <NSObject> {
Class isa;
}

NSObject类中只有一个名为isaClass类型的变量,跳转到Class的定义我们可以看到:
1
2
3
4
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;

Class为指向objc_class的指针,而objc_class就代表了在Objectivec中一个类的定义。其源代码定义如下:
1
2
3
4
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache;

我们看到objc_class继承自objc_object,而objc_object的定义如下:
1
2
3
struct objc_object {
private:
uintptr_t isa;

objc_object只保存了一个isa指针,在原代码中我们还可以看到

typedef struct objc_object *id;

看到这里一切应该都已经明了了。我们知道在ObjectiveC中每一个对象都是一个id,所以objc_object就是我们每一个对象在内存中的结构,它保存了一个指向objc_class的指针,这个指针就指向对象所对应的类在内存中的位置。

既然objc_class代表了ObjectiveC中的类,那么结构中必然需要存储类的相关信息,包括类的名字,成员函数的位置等信息,在ObjectiveC2.0中,这些信息被封装在了class_rw_tclass_ro_t当中,他们代码定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
struct class_rw_t {
uint32_t flags;
uint32_t version;

const class_ro_t *ro;

union {
method_list_t **method_lists; // RW_METHOD_ARRAY == 1
method_list_t *method_list; // RW_METHOD_ARRAY == 0
};
struct chained_property_list *properties;
const protocol_list_t ** protocols;

Class firstSubclass;
Class nextSiblingClass;
};

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;
const method_list_t * baseMethods;
const protocol_list_t * baseProtocols;
const ivar_list_t * ivars;

const uint8_t * weakIvarLayout;
const property_list_t *baseProperties;
};

至此我们基本上了解了ObjectiveC中对象的组织形式,总结如下:

每一个ObjectiveC对象都保存了一个isa指针指向其所对应的类的实现objc_class,而objc_class中保存了类父类,名称,函数列表,以及Protocol等信息。

但是有些内容还不是特别清晰:

  • 对象的成员变量应该是局部于对象的,不应该保存在objc_class中,对于成员变量这部分的实现还不清晰
  • 对于大部分文章中提到的元类在代码中是如何体现的? 目前我在代码中没有看到

以上ObjectiveC基本的对象模型,在这个对象模型的基础上ObjectiveC提供给了我们丰富的Runtime特性以及OO的支持,以后我们会进一步深入了解一些重要特性的实现。

我阅读的代码版本是Objc4-551,是官方开源的最新代码,如果文章中有错误或者有更详尽的看法请留言,共同学习进步。