上一篇我们讲到iOS方法的底层的本质是消息!!!这一篇我们分析消息的走态
- Root class (class)其实就是NSObject,NSObject是没有超类的,所以Root class(class)的superclass指向nil。
- 每个Class都有一个isa指针指向唯一的Meta class
- Root class(meta)的superclass指向Root class(class),也就是NSObject,形成一个回路。
- 每个Meta class的isa指针都指向Root class (meta)。
- Root class (meta)的isa指针都指向自己
这里我记录一个重要的点:
- 对象方法存在类里面
- 类方法存在元类里面
- 元类的方法存在根元类
这是非常重要的,如果我们没有捋清楚,就无法得知我们的消息接受者!!!
isa 又是什么?
所谓isa指针,在OC中对象的声明是这样的
typedef struct objc_object {
Class isa;
} *id;
对象本身是一个带有指向其类别isa指针的结构体。
当向一个对象发送消息的时候,实际上是通过isa在对象的类别中找到相应的方法。我们知道OC中除了实例方法之外还有类方法,那么类别是否也是个对象呢?
typedef struct objc_class *Class;
struct objc_class {
Class isa;
Class super_class;
/* followed by runtime specific details... */
};
从上面类别的结构看来,类别也是一个对象,它拥有一个指向其父类的指针,和一个isa指针。当一个类别使用类方法时,类别作为一个对象同样会使用isa指针找到类方法的实现。这时,isa指向的就是这个类别的元类。
也就是说
元类是类别的类。
所有的类方法都储存在元类当中。
众所周知Objective-C(以下简称OC)中的消息机制。消息的接收者可以是一个对象,也可以是一个类。那么这两种情况要是统一为一种情况不是更方便吗?苹果当然早就想到了,这也正是元类的用处。苹果统一把消息接收者作为对象。等等,这是说,类也是对象?yes,就是这样。就是说,
OC中所有的类都一种对象。由一个类实例化来的对象叫实例对象
,这好理解,那么,类作为对象(称之为类对象)
,又是什么类的对象?当然也容易猜到,就是今天的主题——元类(Metaclass)。现在到给元类下定义的时候了:元类就是类对象所属的类
。所以,实例对象是类的实例,类作为对象又是元类的实例
。已经说了,OC中所有的类都一种对象,所以元类也是对象,那么元类是什么的实例呢?答曰:根元类,根元类是其自身的实例