runtime系列

类和对象在runtime中的描述

2017-11-07  本文已影响0人  coldLeon

类在runtime中的描述如下:

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
} ;

当然,以上是简化过的,略去了不重要的内容。
再来看下Class的定义

typedef struct objc_class *Class;

合并一下,就能得到下面的等效表达

struct objc_class {
    struct objc_class *isa;
};

那么对象呢?同样,来看描述

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};
typedef struct objc_object *id;

Class的定义跟上面类的描述一致,所以也可以合并为

struct objc_object {
    struct objc_class *isa;
};

我们这两个定义放在一起来看下:

struct objc_class {
    struct objc_class *isa;
};
struct objc_object {
    struct objc_class *isa;
};
 
typedef struct objc_class *Class; //类  (class object)
typedef struct objc_object *id;   //对象 (instance of class)

通过上面的声明可以看出,Class是一个指向objc_class结构体的指针,而id是一个指向objc_object结构体的指针,其成员isa是一个指向objec_class结构体的指针。

凡是首地址是*isa的struct指针,都可以被认为是objc中的对象。运行时可以通过isa指针,查找到该对象是属于什么类,也就是当我们向某个对象发送某个消息时,运行时库会根据实例对象的isa指针找到这个实例对象所属的类。Runtime库会在类的方法列表及父类的方法列表中去寻找与消息对应的selector指向的方法。

所有的类自身也是一个对象,我们可以向这个对象发送消息(即调用类方法)。如:

NSString *string = [NSString string];

我们给NSString发送了一个string的消息,也就是可以把NSString也看成是一个对象,那么它就包含一个指向其所属类的指针了,这个指针是指向啥的呢?这就是接下来我们要说的meta-class了。它是一个类对象所属的类。当我们向一个对象发送消息时,runtime会在这个对象所属的这个类的方法列表中查找方法;而向一个类发送消息时,会在这个类的meta-class的方法列表中查找。
好了,又一个问题来了,meta-class也是一个类,也可以向它发送一个消息,那么它的isa又是指向什么呢?为了不让这种结构无限延伸下去,Objective-C的设计者让所有的meta-class的isa指向基类的meta-class,以此作为它们的所属类。即,任何NSObject继承体系下的meta-class都使用NSObject的meta-class作为自己的所属类,而基类的meta-class的isa指针是指向它自己,实在是机智。
根据上面我们讲的,就能得到下面这张经典的类与对象的关系图了,可以比对这张图再重读下上面说的,能理解得更透彻点。


1510064850760.jpg
上一篇 下一篇

猜你喜欢

热点阅读