iOS对象的本质

722 阅读3分钟

一.Clang

Clang是⼀个C语⾔、C++、Objective-C语⾔的轻量级编译器。源代码发布于BSD协议下。

Clang将⽀持其普通lambda表达式、返回类型的简化处理以及更好的处理constexpr关键字。

Clang是一个由Apple主导编写,基于LLVM的C/C++/Objective-C编译器。

clang -rewrite-objc main.m -o main.cpp 把⽬标⽂件编译成c++⽂件 UIKit报错问题

clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-13.0.0 -isysroot / Applications/Xcode.app/Contents/Developer/Platforms/ iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.0.sdk main.m xcode安装的时候顺带安装了xcrun命令,xcrun命令在clang的基础上进⾏了 ⼀些封装,要更好⽤⼀些 xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp (模拟器) xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp (⼿机)

二.对象的本质

通过clang可以查看对象的源码

例如LGperson的代码如下 6351623593447_.pic.jpg

clang可看到底层源码

6361623593458_.pic.jpg

可以得出对象的本质是结构体 Class 的本质类型是objc_class

WeChatf4d8f205c4fc3be846ed09cbb67c47ba.png

同时我们也能获的对象的set和get方法

WeChat01b019cdb6f095ae68c7
9aabb4ec796a.png

如要获取对象的属性值,首先知道person的首地址,然后平移ivar所在空间的平移量,然后才能获取到属性的地址,然后才会获取到属性值。 image.png

三.联合体位域 使用联合体位域是为了节省内存空间,如何节省呢?

例如结构体如下:

WeChat80fd6a29781e28f633664ab96cea8baf.png 结构体占用4字节内存 4*8=32 位 =0000 0000 0000 0000 0000 0000 0000 1111 其实4位 1个字节就可以满足要求,所以造成了3倍的浪费

为了节省空间可以用如下方式表示:

WeChata8acae3151f2cf9a0480def55609ee5d.png

那么一个字节就可以标识

若我们用如下方式表示:

WeChat0461e9816909a19630bf036a1ccf138f.png front 为1位,back为2位,left为6位,right为1位,因为这儿存在互斥,标识之后内存占用量为2字节。

接下来我们可以看到如下结构体的成员变量可以同时被赋值, image.png

但在联合体重,成员变量不能被同时被赋值,但是其余成员变量内存是不可用的为脏数据。

结构体(struct)中所有变量是“共存”的——优点是“有容乃⼤”,全⾯;缺点是struct内存空间的分配是粗放的,不管⽤不⽤,全分配。

联合体(union)中是各变量是“互斥”的——缺点就是不够“包容”; 逻辑教育 但优点是内存使⽤更为精细灵活,也节省了内存空间。

四.isa

isa的底层 image.png

为什么要有isa_t? 在表现一个类的地址过程中会出现nonPointerIsa,不再是简单的指针。类的对象就是一个指针,我们用64位来存储一个指针会大大的浪费,那么我们就会把是否正在释放、引用计数,weak,关联对象,析构函数等等放在这个内存中,所以出现了nonPointerIsa。可以在位域中进行查看。

image.png

对象通过isa掩码就能得到类信息

image.png

image.png

通过平移查看:

image.png

image.png