03.对象的isa与superclass

2021-08-19  本文已影响0人  白开了杯水
之前章节

01.OC实例对象的本质
02.OC有几种对象

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并不指向类对象呢,其实并不是的,从64位开始,要对isa进行一下位运算 & ISA_MASK 才能得到真实地址,所以需要位运算一下

接下来我们来看看类对象的isa与元类对象的地址是否一致,如下图 类对象的isa和元类对象地址对比

从输出结果我们可以看到,俩个地址相同,不需要做位运算~

superclass

我们利用了isa成员变量解决了调用对象方法和调用类方法的问题,那么现在遇到了另一个问题了,如以下代码 继承关系的调用

我们把Person和Student转为图片大概是这样子


Person和Student

问题:Student继承了Person,那么它该怎样找到Person的run方法的呢?
如果你是苹果开发人员,你就会想,跟isa一样,弄个成员变量引用Person不就行了,这时superclass就产生了,每个对象都会有一个superclass,总结一下

这里上一张非常经典的图


isa与superclass的流转图

举个例子:实例对象调用实例方法流程

实例对象调用实例方法流程图

再举个例子:类对象调用类方法流程


类对象调用类方法流程

注意,如果元类基类都没有该方法,会去对象基类中查找,如果没有的话才会进入消息转发流程

isa扩展

isa现在已不是单纯的地址值,而是一个union共用体,如图

isa的源码结构

它可以存储更多的东西,但内存空间还是跟以前一样,各个字段作用如下图:

isa各成员作用

感谢观看!

上一篇下一篇

猜你喜欢

热点阅读