3.isa指针

一、对象的本质

1.OC类怎么编译成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 (手机)

2.发现的秘密

①OC的类就是结构体,最底层的就是objc_object结构体

image.png

②Class是objc_class结构体,id是objc_object结构体

image.png

③函数前面有2个隐式参数 self cmd,获取name的时候是以self + OBJC_IVARLGPerson_LGPersonkcName这样的方式(self首地址+OBJC_IVARLGPerson_LGPerson_kcName偏移地址获取的)
image.png

二、联合体位域

结构体:会为所有的成员分配内存,不管是否用到

联合体:成员之间是互斥关系,同一时间只有一个,内存为最大的那个成员的内存

image.png

三、nonPointerIsa的分析

①isa是isa_t的联合体,isa_t的定义如下

image.png

②解读

nonpointer:表示是否对 isa 指针开启指针优化 0:纯isa指针,1:不止是类对象地址,isa 中包含了类信息、对象的引用计数等

has_assoc:关联对象标志位,0没有,1存在

has_cxx_dtor:该对象是否有 C++ 或者 Objc 的析构器,如果有析构函数,则需要做析构逻辑, 如果没有,则可以更快的释放对象

shiftcls:
存储类指针的值。开启指针优化的情况下,在 arm64 架构中有 33 位用来存储类指针。

magic:用于调试器判断当前对象是真的对象还是没有初始化的空间

weakly_referenced:标志对象是否被指向或者曾经指向一个 ARC 的弱变量,没有弱引用的对象可以更快释放。

deallocating:标志对象是否正在释放内存

has_sidetable_rc:当对象引用技术大于 10 时,则需要借用该变量存储进位

extra_rc:当表示该对象的引用计数值,实际上是引用计数值减 1, 例如,如果对象的引用计数为 10,那么 extra_rc 为 9。如果引用计数大于 10, 则需要使用到下面的 has_sidetable_rc。

四、通过isa指针得到class

类信息存储在shiftcls中,低3位和高17位存储别的信息,如何通过偏移得到中间的44位?结果如图,最后得到的地址和直接打印类的地址是一样的,完美
image.png

今天写到这吧,下篇接着搞

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享