题记
正如我们前文提到,OC的每个对像中都会有一个isa指针,每个类中都会有一个superclass指针,那么它们有什么用?实例对象,类对象,元类对象之间又有什么联系呢?
正题
isa指针
首先我们准备一个继承自NSObject的JJPerson类,定义一个对象方法和一个类方法,然后我们分别调用这两个方法。
但正如我们前文提到,类方法实际在元类对象中而不是类中,对象方法实际存放在类中而不是实例对象中,那它们分别是怎么调用到并没有存放在自身的东西呢?这时候就是isa指针发挥作用了。
如上图我们看到:
instance的isa指向class
当调用对象方法时,通过instance的isa找到class,最后找到对象方法的实现进行调用
class的isa指向meta-class
当调用类方法时,通过class的isa找到meta-class,最后找到类方法的实现进行调用
OC对象就可以通过isa指针这样串联起来
superclass指针
我们把问题变得稍微复杂一些,我们为JJPerson增加一个子类JJStudent,同样顺手为它准备一个对象方法和一个类方法。
正如我们所知,student继承自person,它是可以调用父类的方法的。
但是Person的对象方法和类方法都是存放在Person的类对象和元类对象中,Student的类和实例对象是怎么调用它们的呢?这样的情况下isa指针看起来已经不能满足我们的需求了,那这时候就需要superclass指针。
-
当Student的instance对象要调用Person的对象方法时,会先通过isa找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用
- 当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用
总结
这张经典的图相信很多iOS开发者都看过,它很好地指出了isa和superclass在OC对象之间所担任的联系
综合我们上面提到的例子,我们可以为这张图加上备注方便理解
instance的isa指向class
class的isa指向meta-class
meta-class的isa指向基类的meta-class
基类的meta-class的isa指向自己
class的superclass指针指向父类(如果没有父类则指向nil)
meta-class的superclass指向父类的meta-class
基类的meta-class的superclass指向基类的class(NSObject)
instance调用对象方法的轨迹
isa找到class,方法不存在,就通过superclass找父类
class调用类方法的轨迹
isa找meta-class,方法不存在,就通过superclass找父类