OC对象的本质

本篇文章要点

一、OC对象的本质是什么

二、内存对齐原理

一、OC对象的本质是什么

先说结论,OC对象本质上就是一个结构体。那么接下来上代码感受一下。

任何一门编程语言都离不开编译器,OC也不例外,XCode的默认编译器是clang,今天我们通过clang命令来编译一下代码。首先 我们再创建一个新工程,我们在mian.m文件中添加一个Person类 ,因为我们只编译main.m文件,所以要把无关文件的引入先注释。


20268162-ef53d441a0c4e239.jpg

然后进入到main.m所在路径 使用 clang -rewrite-objc main.m -o main.cpp 对main.m文件进行编译。


20268162-d35a340e3979ca80.png

之后我们就得到一个编译后的main.cpp的C++文件


20268162-0c97407ebc3ff60b.jpg

打开找到Person_IMPL 这个结构体 这就是我们OC对象编译过后的本质。结构体的第一个实际上是isa (isa如果不太熟 可以暂时理解为指向类的一个指针)接下来就是对象的成员变量或属性,成员变量没有按照我们写的顺序 是因为内存对齐优化处理的结果

20268162-59d947cb5d0468cc.jpg

二、内存对齐原理

先来看两个结构体 两个数据类型都一样 顺序不一样 按照类型计算大小都应该为21 经打印结果显示 memory1的内存大小为32 memory2的内存大小为24 这是为什么呢? 计算机并不会像我们这么聪明 有一存一 有二存二 而是制定了一定的规则去存取数据 回到结构体上 两个的大小都是8的倍数 没错 这就是因为8字节对齐 结构体后面注释是表示的大小 +号代表补齐字节 这样一看 也就理解为什么是32和24了

我的OC对象也本质上也是一个结构体 所以计算对象申请内存也是8字节对齐,需要注意的是 我们的对象是经过内存优化了的 不会因为属性的顺序不同而有不同的大小

struct memory1{
    long a;//8
    int  b;//4 +4
    long c;//8
    char d;//1 +7
};//32
struct memory2{
    long a;//8
    int  b;//4
    char d;//1 +3
    long c;//8
};//24
NSLog(@"%lu-----%lu",sizeof(struct memory1),sizeof(struct memory2));

再来拓展一个知识点 系统为对象开辟空间也有一个对齐原则 看下面代码 打印结果是40和48 40是计算p对象的内存大小 48是系统为p对象开辟的空间大小(malloc_size()是源码中为对象开辟空间的函数) 查看源码得知是16字节对齐 这里就不贴源码了 有兴趣的可以自己研究一下

    Person *p = [Person alloc];
    p.name = @"lucy";
    p.sex = @"女";
    p.Id = @"01";
    p.age = 18;
    NSLog(@"%lu-----%lu",class_getInstanceSize([p class]),malloc_size((__bridge const void *)(p)));

总结:对象申请内存是8字节对齐 系统为对象开辟空间是16字节对齐

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容