本篇文章要点
一、OC对象的本质是什么
二、内存对齐原理
一、OC对象的本质是什么
先说结论,OC对象本质上就是一个结构体。那么接下来上代码感受一下。
任何一门编程语言都离不开编译器,OC也不例外,XCode的默认编译器是clang,今天我们通过clang命令来编译一下代码。首先 我们再创建一个新工程,我们在mian.m文件中添加一个Person类 ,因为我们只编译main.m文件,所以要把无关文件的引入先注释。

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

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

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

二、内存对齐原理
先来看两个结构体 两个数据类型都一样 顺序不一样 按照类型计算大小都应该为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字节对齐