美文网首页
03.对象的isa与superclass

03.对象的isa与superclass

作者: 白开了杯水 | 来源:发表于2021-08-19 17:34 被阅读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是指向另一个对象,那么是不是它的地址就是另一个对象的地址呢?
    首先我们来看看实例对象的isa和类对象的地址是否一致,如下图


    实例对象的isa和类对象地址对比

    从输出结果我们可以看到,俩个地址是不同的,那是不是代表isa并不指向类对象呢,其实并不是的,从64位开始,要对isa进行一下位运算 & ISA_MASK 才能得到真实地址,所以需要位运算一下

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

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

    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各成员作用

    感谢观看!

    相关文章

      网友评论

          本文标题:03.对象的isa与superclass

          本文链接:https://www.haomeiwen.com/subject/eqcabltx.html