其他分享
首页 > 其他分享> > iOS 底层探索篇 —— OC对象本质 & noPointerIsa

iOS 底层探索篇 —— OC对象本质 & noPointerIsa

作者:互联网

iOS 底层探索篇 —— OC对象本质 & noPointerIsa

一. 对象的本质探索

Clang

clang是一个由Apple主导编写,基于LLVM的C/C++/OC的编译器

操作代码

在这里插入图片描述

实例

在这里插入图片描述
通过这个指令,就可以把main.m 编译成 main.cpp 文件,可以更好的观察底层的一些结构及实现的逻辑,方便理解底层原理。

对象的本质

对象在底层的本质是结构体,那么是如何得到这个结论的呢。
首先我们在main.m 文件中声明一个类LGPerson,有一个属性 NSString LSName(为了避免是巧合,取一个特殊的名字)。

在这里插入图片描述
然后我们按照上文中的方法将 main.m 编译成 main.cpp 文件,然后将main.cpp 文件打开,并且搜索一下我们的类LGPerson。

在这里插入图片描述

我们可以看到LGPerson 中有两个参数
第一个参数就是isa,是继承自NSObject_IMPL,属于伪继承,伪继承的方式是直接将NSObject_IMPL结构体定义为LGPerson中的第一个属性,意味着LGPerson 拥有 NSObject_IMPL中的所有成员变量。
第二个参数就是我们的成员变量 LSName。
在这里插入图片描述
同时我们注意到,在main.cpp中,LGPerson的本质类型是 objc_object,这是为什么呢?
这是因为LGPerson继承自NSObject, 而NSObject 在底层中的实现就是objc_object,因此LGPerson的本质类型是 objc_object。
在这里插入图片描述

Class类型的本质类型

在这里插入图片描述
我们在main.cpp中寻找,找到上图可知, 得出class 是 objc_class 的结构体指针。并且我们也可以得知为什么id 不加*, 因为底层中已经加过了。

getter 和 setter

继续在main.cpp 中寻找,我们找到
在这里插入图片描述
从名字以及参数中,我们大致可以看出这个是LGPerson 的getter 和setter 方法,但是这个参数我们从来没有见到过。这些参数是隐藏参数
为什么return 是 self + objc_ivar 呢?因为我们需要拿到内存地址才能拿到内存的值,拿到person首地址,然后拿到ivar 空间平移的量进行平移,才能获得LSName所在的地址,拿到地址才能获取里面的值。

二. 联合体位域

在这里插入图片描述
在这个结构体中,存了四个bool值,每个bool值占一个字节,根据内存对齐原则,可以得出这个struct总共占了4个字节。

在这里插入图片描述
而用sizeof可以得出,这个struct真的是占用了4个字节。显然,bool 不是 0 就是1,实际上用4位去存就可以了,用四个字节去存有点浪费内存了。

位域

这里,我们可以用位域,来指定这个成员占多少位。举个

标签:字节,对象,iOS,OC,内存,noPointerIsa,isa,main,LGPerson
来源: https://blog.csdn.net/LinShunIos/article/details/117769470