OC对象 - 本质
-
我们平时编写的Objective-C代码,底层实现其实都是C\C++代码

-
所以Objective-C的面向对象都是基于C\C++的数据结构实现的
-
思考:Objective-C 的对象、类主要是基于C\C++的什么数据结构实现的?
-
- 我们的对象、类,会有很多不同数据类型的属性,所以最合适的C\C++数据结构应该是:
结构体
- 我们的对象、类,会有很多不同数据类型的属性,所以最合适的C\C++数据结构应该是:
1 窥探OC对象的本质
1.1 将Objective-C代码转换为C\C++代码
使用如下命令:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件
如果需要链接其他框架,使用-framework参数。比如-framework UIKit
- 注意如上命令的相关参数:arm64
- 我们知道运行平台会有
模拟器(i386)、armv7(32位)、arm64(64位),最终的汇编代码在不同平台上是会有所区别的。我们现在的iPhone都是arm64,所以我们统一转为arm64
1.1.1 实操
- 我们来新建一个工程。为了方便,我们直接新建macOS的Command LineTool工程

- 在main文件里面,我们初始化一个
NSObject对象
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj = [[NSObject alloc] init];
}
return 0;
}
- cd到工程目录下,执行转换命令
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
- 此时同目录下生成
main-arm64.cpp文件,我们将其拖入项目中查看



- 此时我们把
main-arm64.cpp从编译列表去掉,否则项目不能正常编译

- cpp文件有两万多行代码

1.2 分析生成的C++代码
- 我们查找NSObject 的实现

struct NSObject_IMPL {
Class isa;
};
- NSObject对应实现就是这样一个结构体,可以看到里面只有一个
isa成员
1.3 结论

- NSObject底层实际是
struct NSObject_IMPL结构体 - 结构体中仅有一个
isa成员 NSObject *obj = [[NSObject alloc] init];通过alloc,相当于分配了一段存储空间给这个结构体,然后把创建出来的对象的内存地址赋值给*obj这个指针,所以*obj存储的就是这个对象的内存地址isa的地址其实就是这个结构体的地址,因为结构体里面只有isa一个成员
@oubijiexi
本文详细解释了Objective-C中的对象和类如何基于C++的数据结构实现,通过将代码转换为C++并分析生成的代码,揭示了NSObject底层是一个包含isa成员的结构体,isa用于存储对象的内存地址。
1543





