类和对象在runtime中的描述

类在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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容