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

2021/6/11 18:26:22

本文主要是介绍iOS 底层探索篇 —— OC对象本质 & noPointerIsa,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

    • 一. 对象的本质探索
      • Clang
        • 操作代码
        • 实例
      • 对象的本质
      • Class类型的本质类型
      • getter 和 setter
    • 二. 联合体位域
      • 位域
      • 结构体(struct)所有变量是共存的
      • 联合体(union)中是各变量是互斥的
    • 三. noPointerIsa
      • 1. initIsa
      • 2. initIsa(cls, false, false);
      • 3. isa_t
      • 4. union isa_t
        • 针对两种不同平台,其isa的存储情况如图所示

一. 对象的本质探索

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的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程