首先,你要先弄清楚什么是类,什么是对象。(为了说清楚这个问题,先举个栗子:类—>对象—>实例:人类是类;某个人是对象;你是实例;实例本身也是对象。这下基本能理解其中的差别了,要是还是搞不清楚,自己去google一下吧。)
对象
在Objective-C中,每一个对象都是某个类的实例,且这个对象的isa指针指向它所属的类。打开 objc-private.h文件,在第126行可以看到 Objective-C 对象的定义struct objc_object ,Objective-C中对象本质上是结构体对象,其中isa是它的唯一私有变量。
同样的,在第48行到第52行,可以找到 Class 和 id 类型定义,这也是为什么 id类型可以指向任意对象的原因。其中objc_class 就是 Objective-C 中类的定义。
类
对象的类不仅描述了对象的数据:对象占用内存大小,成员变量的类型布局等,还描述了对象的行为:对象能响应的信息,实现的实力方法(很多对runtime的讲解的文章,其实就是在这一块做文章)等。因此,当我们调用[receiver message]给一个对象发送消息的时候,这个对象能否响应这个消息就需要通过isa找到它所属的类(包括superClass)才能知道。
打开 objc-runtime-new.h ,在687行可以找到 Objective-C 中 struct objc_class 的定义。可以看到Objective-C中类也是一个结构体对象,并且继承了 struct objc_object 。
所以: Objective-C 中的类本质上也是对象,我们称之为类对象。按照之前说的,所有的对象都是某个类的实例,那么类对象又是什么什么类的实例,这是个值得思考的问题。
我们知道 Objective-C 中有一个非常特殊的NSObject,绝大部分的类都继承自它,它是 Objective-C 中两个rootClass钟的一个,另一个是NSProxy(另一篇文章有)。打开 NSObject.h ,可以看到NSObject 类就只有一个成员变量 isa, 所有继承自NSObject得类也都会有这个成员变量。
元类
本质上讲, Objective-C 中的类也是对象,它也是某个类的实例,这个类我们称之为元类(metaclass)。
因此,我们可以调用类方法,比如[NSObject new]来给类对象发送消息。同样的,类对象能否响应这个消息,要通过isa找到类对象所属的类(元类)才能知道。也就是说,实例方法保存在类中,而类方法保存在元类中。
元类也是对象(元类对象),元类也是某个类的实例,这个类我们称之为根元类(root metaclass)。特殊的是:所有的元类所属的类都是同一个根元类(当然根元类也是元类,所以它所属的类也是根元类,即它本身)。根元类所指的就是根类的元类,具体说就是根类NSObject 对应的元类。
上经典图:通过上面的解析,再来看这张图,清晰多了。
原文:http://my.oschina.net/caijunrong/blog/528651