美文网首页iOS 底层原理探究
NSObject本质(二)继承体系中的实例对象占用多少个字节?

NSObject本质(二)继承体系中的实例对象占用多少个字节?

作者: PerryMorning | 来源:发表于2019-10-29 22:40 被阅读0次

上一篇文章中,我们知道了一个NSObject对象,因为只有一个isa指针,在64位环境下系统分配了16个字节,但是实际只占用8个字节。这个可以分别通过malloc_size() 和 class_getInstanceSize()方法来获取。具体可以参看:一个NSObject对象在内存中占用多少个字节?

在实际开发过程中,我们用到的类都是继承自NSObject对象,那么一个继承自NSObject对象的实例对象究竟占用多少个字节呢?我们一起来探讨一下。

首先我们先创建一个命令行函数,构建一个继承体系,Student --> Person -->  NSObject,如图所示:

思考:现在Person的实例对象和Student的实例对象在64位环境下,分别占多少字节?

按照同样的方法,我们通过clang编译器将main.m函数转换成C++函数,在命令行中输入:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp

得到main.cpp函数,打开后,依旧搜索Person_IMPL和Student_IMPL,得到如下结果:

通过编译后的代码,我们也看到继承是如何实现的,Person类首先将其父类NSObject的成员变量继承过来,然后加上自己的成员变量。同样的道理,Student类先将其父类Person的成员变量继承过来,然后加上自己的成员变量。

首先我们来思考Person类,因为Person类中包含两部分,第一部分是NSObject的成员变量,也就是isa指针,第二部分是一个整形变量age。系统为NSObject分配了16个字节,isa指针只占用8个字节,age变量占用4个字节。那么age变量会不会在NSObject分配的16个字节的后8个字节中呢?如果是这样子的话,Person类的实例变量也就是占用16个字节内容。

同样的道理,Student类继承自Person类,按照刚才的假设,Person类分配了16个字节大小,实际占有12个字节,还有4个字节,刚好够整形score进行存储,实际是否是这样呢?

我们通过代码来验证一下:

结果和我们猜测的一样,Person类和Student类的实例都是分配了了16个字节,实际占用16个字节大小,也就是把NSObject剩余的8个字节充分利用了起来。

当然我们也可以像上篇文章中所讲的,通过探测内存布局,从侧面进行二次验证:

从内存布局中我们可以看到,系统分配了16个字节的连续空间,其中前8个字节是isa指针指向的地方,紧接着十六进制 0A 就是我们进行的age的值,十六进制96就是score的值。

这里牵涉一个大小端的问题,在iOS开发中所用的是小端模式,所谓的小端模式就是高位放在高地址,低位放在低地址,简称大大小小。大端模式刚好相反,高位放在低地址,低位放在高地址,简称大小大小。

由于地址从左至右依次增大,age的实际数值就是 0x0000000A = 10,score的值是0x00000096 = 150。

想进一步验证0x00000096是否是score的地址,我们也可以通过lldb调试器,来判断:

首先 student的地址是0x10040f430,向后偏移12个字节,也就是0x10040f43C,使用memory write 0x10040f430 10 将0x10040f43C的值改为0x10,修改完成后,查看score的值,变成了16,完美验证了我们的猜想。

到这里,关于继承体系中实例对象的内存布局,我们已经清楚了。总结一下:

   1.子类会继承父类的成员变量,然后将自己的成员变量紧挨其后;

    2.当父类中有剩余空间,能够存放子类的成员变量时,将子类的成员变量放在父类所开辟的空间后面,并没有分配新的内存空间。假如父类分配的内存空间已经占用满了呢?会发生什么情况,这个问题我们留到下篇文章进行分析,会牵涉到内存对齐的知识。

    3.大小端模式,iOS开发中用到的都是小端模式,即大大小小,高位放在高地址,低位放在低地址。

相关文章

  • NSObject本质(二)继承体系中的实例对象占用多少个字节?

    上一篇文章中,我们知道了一个NSObject对象,因为只有一个isa指针,在64位环境下系统分配了16个字节,但是...

  • nsobject

    一个NSObject对象占用多少个字节16个,NSObject 里面的isa指针占用了8个自字节,malloc库在...

  • OC底层基础:面试题

    一、NSObject本质 一个NSObject对象占用多少内存(16)系统分配了16个字节给NSObject对象(...

  • iOS OC对象的本质

    实例对象 一个NSObject对象占用多少内存? 系统分配了16个字节给 NSObject 对象(通过 mallo...

  • OC对象的本质 1--一个OC占用多少内存

    OC 对象本质是结构体类型 即 一个NSObject对象占用多少内存? 系统会分配16个字节给NSObject对象...

  • 01.OC实例对象的本质

    你知道NSObject实例对象占用了多少内存么?要回答这道题,我们要探索下OC实例对象的本质,而实例对象的本质其实...

  • NSObject

    NSObject对象占用几个字节? NSObject占用至少16个字节、通过malloc_size获取。但是只只用...

  • iOS面试题-一个NSObject对象占用多少个字节?

    一个NSObject对象占用多少个字节? 在Objective-C中,我们可以通过一些方法来获取一个NSObjec...

  • IOS精选面试题(一)

    一个NSObject对象占用多少内存 系统分配了16个字节给NSObject对象 但是NSObject对象的内部只...

  • ios面试题

    1 NSobject本质是什么,占用多少内存 2 一个自定义对象占多少内存 对象实际 一个isa指针占用8个字节I...

网友评论

    本文标题:NSObject本质(二)继承体系中的实例对象占用多少个字节?

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