在Objective-C中,对象的类由isa指针标示,isa指向了对象的类。Objective-C中一个对象的基本定义以下: 函数
typedef struct objc_object { Class isa; } *id;
这就是说,任何起始于指向类的指针的数据类型,都被当作objc_object。因而,Objective-C中的全部类都被当作了对象。 spa
实际上,objc_class定义以下: 指针
typedef struct objc_class *Class; struct objc_class { Class isa; Class super_class; /* followed by runtime specific details... */ };
Meta-class与类类似,也是一个对象。类有实例对象,而类可看做是meta-class的实例,即类的isa指向它。它有这么些特性,结合图1进行理解。 code
l Meta-class包含了类的类方法; 对象
l 类和meta-class成对出现; 继承
l Meta-class也有继承关系; ci
l 每一个类都有属于本身的惟一的meta-class; class
l 全部的meta-class的isa都指向基类的meta-class,基类的meta-class指向自身;基类的meta-class的父类是基类自身,即全部的类和meta-class都继承自基类(NSObject)。 object
图1 实例、类、Meta-class的关系图 select
为什么须要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。