03.对象的isa与superclass
之前章节
isa
这一节我们来讲一下isa,根据源码我们知道,不管是实例对象、类对象、元类对象,它们都有isa和superclass,why?让我们先忽略它们来看一个场景吧!如下图代码,我们创建了一个person对象
Person对象的方法调用
根据第二章节我们知道,实例方法是存在类对象中,也就是run这个方法其实是在[p class]类对象中,如下图:
Person的实例对象与类对象
那我一个p的实例对象,怎么去找到类对象的实例方法run呢?如果是你来开发的话,你可能会想,那在实例对象中,加一个类对象的引用不就好了,没错!苹果就是这样做的,这样子isa就应运而生~如下图
加一个isa成员变量来找到类对象
同理:当Person调用类对象类方法say时,要去元类查找类方法say,这时类对象也需要添加一个isa对元类的指向,如下图
类对象isa指向元类对象
我们从问题入手来模拟苹果开发人员创建isa成员变量解决问题,讲述了isa的作用,总结一下:
- 实例对象的isa指向类对象
- 类对象的isa指向元类对象
- 元类对象的isa全部都指向基类元类对象
isa的细节
既然isa是指向另一个对象,那么是不是它的地址就是另一个对象的地址呢?
首先我们来看看实例对象的isa和类对象的地址是否一致,如下图
实例对象的isa和类对象地址对比
从输出结果我们可以看到,俩个地址是不同的,那是不是代表isa并不指向类对象呢,其实并不是的,从64位开始,要对isa进行一下位运算 & ISA_MASK 才能得到真实地址,所以需要位运算一下
从输出结果我们可以看到,俩个地址相同,不需要做位运算~
superclass
我们利用了isa成员变量解决了调用对象方法和调用类方法的问题,那么现在遇到了另一个问题了,如以下代码 继承关系的调用我们把Person和Student转为图片大概是这样子
Person和Student
问题:Student继承了Person,那么它该怎样找到Person的run方法的呢?
如果你是苹果开发人员,你就会想,跟isa一样,弄个成员变量引用Person不就行了,这时superclass就产生了,每个对象都会有一个superclass,总结一下
- class对象的superclass指向父类的class,如果没父类,为nil
- meta-class的superclass指向父类的meta-class
- 基类的meta-class的superclass指向基类的class
这里上一张非常经典的图
isa与superclass的流转图
举个例子:实例对象调用实例方法流程
实例对象调用实例方法流程图再举个例子:类对象调用类方法流程
类对象调用类方法流程
注意,如果元类基类都没有该方法,会去对象基类中查找,如果没有的话才会进入消息转发流程
isa扩展
isa现在已不是单纯的地址值,而是一个union共用体,如图
isa的源码结构它可以存储更多的东西,但内存空间还是跟以前一样,各个字段作用如下图:
isa各成员作用感谢观看!