1. Objective-C中的对象
在Objective-C中,对象的类由isa指针标示,isa指向了对象的类。Objective-C中一个对象的基本定义如下:
typedef struct objc_object {
Class isa;
} *id;
这就是说,任何起始于指向类的指针的数据类型,都被当做objc_object。于是,Objective-C中的所有类都被当做了对象。
实际上,objc_class定义如下:
typedef struct objc_class *Class;
struct objc_class {
Class isa;
Class super_class;
/* followed by runtime specific details... */
};
2. 什么是meta-class
Meta-class与类相似,也是一个对象。类有实例对象,而类可看作是meta-class的实例,即类的isa指向它。它有这么些特性,结合图1进行理解。
l Meta-class包含了类的类方法;
l 类和meta-class成对出现;
l Meta-class也有继承关系;
l 每个类都有属于自己的唯一的meta-class;
l 所有的meta-class的isa都指向基类的meta-class,基类的meta-class指向自身;基类的meta-class的父类是基类自身,即所有的类和meta-class都继承自基类(NSObject)。
图1 实例、类、Meta-class的关系图
3. 为何需要meta-class
为何需要meta-class?这与runtime的消息机制相关。
当向对象发送消息时,
3.1. 若对象为实例对象:[instanceObj foo]
runtime根据isa找到所属类。该类包含
一个实例方法列表(objc_method_list)
一个指向父类的指针,用于查找父类中的实例方法
查找过程:
在实例对象所属的类中的方法列表中查找名为foo的方法,若没找到,在其父类中继续查找,直到找到根类;若找到,则执行foo方法对应的IMP(函数指针)。若继承关系链中的类都没有,那么会报错误:unrecognized selector sent to instance。其实runtime提供了3种解救方法,可以动态新增方法或转发消息。这里不进行讨论。
3.2. 对象是类对象:[classObj foo]
runtime根据isa找到所属meta-class,它包含
一个类方法列表;
一个指向父类的指针,用于查找父类中的类方法
查找过程:
在类对象对应的meta-class的方法列表中查找名为foo的方法,若没找到,在其meta-class父类中继续查找;若找到,则执行foo方法对应的IMP(函数指针)。若继承关系链中的metal-class类都没有,那么会报错误:unrecognized selector sent to class。