类与元类
类
Objective-C是一个基于类的对象系统,每个对象是一个类的实例,实例的
isa
指针指向了其对应的类。类描述了实例的数据:分配的内存大小;成员变量(
ivar
)类型;布局,以及实例的行为:它响应的选择器和它实现的实例方法。当你发送一个消息给一个实例,
objc_msgSend()
方法会查看该实例对应类(及其父类,如果有)的方法列表来决定调用哪些方法。
每个Objective-C类也是一个对象,也有一个isa
指针和数据,也能响应一些选择器。当你调用一个类方法时(如[NSObject alloc]
),你实际上是给该类的类对象(即该类的isa
指针指向的对象)发送了一个消息。
元类
简单点说,类的
isa
指针指向的对象即为元类。当你调用一个类方法时(如
[NSObject alloc]
),实际上是给该类的元类发送了一个消息。元类是类对象的描述,元类的方法列表里是类方法。当你发送一个消息给一个类时,
objc_msgSend()
会查看其元类(及其父类,如果有)的方法列表来决定调用哪些方法。元类是根元类的实例
元类链与父类链
元类链(即对象的
isa
指针链):实例 -> 类 -> 元类 -> 根元类
(注:根元类的isa指针指向了自己,即根元类的元类就是自己。)类的父类链:
子类 => 父类 => 根类 => nil
元类的父类链:
元类 => 父元类 => 根元类 => 根类
注意
元类的父类链与类的父类链是并行的,因此类方法与实例方法是并行继承的。
根元类的父类是根类,因此每个类都能响应根类的实例方法。
当发送一条消息给一个对象时,对应方法的查找会先从元类链(即
isa
指针链)开始,然后继续在父类链上查找(注:应该是在元类链上未找到才会继续查找父类链)。实例方法由类定义,类方法由元类和根类定义。