以下都是在64bit环境下操作:
我们平时编写的Objective-C代码,底层实现其实都是C\C++代码
在这里我们将main.m 使用clang转成c++文件,也就是在终端输入
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
这样,在文件夹里就会生成main.cpp文件。
然后我们查看nsobject源码,再对比c++里面的源码,
接下来,进入正题了,导入头文件
#import <objc/runtime.h>
#import <malloc/malloc.h>
NSLog(@"%zd",class_getInstanceSize([NSObject class])); // 8
NSLog(@"%zd",malloc_size((__bridge const void *)objc)); // 16
我们发现两者打印的值有偏差,那么问题来了,为什么呢?
接下来,我们进入源码发现,oc对象的本质是一个结构体,
class_getInstanceSize,这是runtime获取实例对象的大小,并不是实际大小,系统真正分配的是16个字节,
,runtime获取的是isa的大小,一个指针也就是8个字节,
malloc_size源码,返回的就是系统分配的内存了,这就能解决为什么打印的不一样了。
接下来,我们再探讨malloc_size为什么打印出来是16,这里我们需要看他的源码https://opensource.apple.com/tarballs/,这是苹果开源的源码,搜索objc4,打开后,下载最大的包,如下图756的,解压后,直接xcode打开,接下来就全看截图吧,第7步的extraBytes为之前传的0。
思考:一个Person对象、一个Student对象占用多少内存空间?
内存对齐:结构体的大小必须是最大成员大小的倍数
person实例对象也就是 isa指针8+age_4 < 16 ,大小为16字节
student实例对象为isa指针8+age_4+no_4 = 16字节
转载:https://blog.csdn.net/hengsf123456/article/details/101012640