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