Object-C的本质
我们平时编写的Objective-C代码,底层实现其实都是C\C++代码
编译顺序所以Objective-C的面向对象都是基于C\C++的数据结构实现的;那么 Objective-C的对象、类主要是基于C\C++的什么数据结构实现的?
答案是结构体,因为只有结构体能存储不同类型的对象。下面我们一步一步验证一下,NSObject 对象的本质是不是就是结构体,需要先将oc代码转成c/c++代码
转换之前我们需要指定一个具体系统以及架构,就以iphone的64位架构来区分,补充一点是模拟器的架构是i386、32bit是arm7、64bit是arm64,所以我们需要执行的代码是
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
然后生成一个main-arm64.cpp对应的c/c++代码,在 main-arm64.cpp 内我们可以找到NSObject_IMPL这个结构体,它就是NSObject的具体实现;因为结构体内只有一个isa成员,所以isa的地址就是当前结构体在内存中的地址,所以obj指针中存储的地址就是isa的地址值。
接下来,延伸一到面试题
问:一个NSObject 对象占用多少内存?
打印结果我们可以看到 malloc_size 返回的的确是16个字节,那么为什么class_getInstanceSize 返回的是8呢?通过查看源码注释我们知道,其实class_getInstanceSize返回的是对象成员变量所占用的大小,但是系统分配的内存的时候,如果你的内存大小小于16,那么会按照16个字节来分配。
答:系统分配了16个字节给NSObject对象,但是NSObject对象内部只使用了8个字节的空间(64bit环境下)