返回

深入探究 Objective-C 底层原理 2:Alloc 内存开辟大小和类型内存对齐

IOS

前言

在 Objective-C 开发中,alloc 方法用于动态创建对象,该方法会开辟一块内存空间用于存储对象的数据。对于类的实例和结构体,内存开辟的大小和对齐方式有特定的规则和限制。深入理解这些机制对于编写高效且健壮的 Objective-C 代码至关重要。

Alloc 内存开辟大小

当使用 alloc 方法创建对象时,底层会调用 calloc 函数分配内存空间。calloc 函数接收两个参数:要分配的元素数量和每个元素的大小。对于 Objective-C 对象,calloc 会分配足够的空间来存储对象的实例变量。

实例变量的大小由类的定义决定。每个实例变量的大小可以通过 sizeof 操作符获取,该操作符返回变量类型所占用的字节数。例如,如果一个类有一个 int 类型的实例变量,那么 sizeof(int) 将返回 4,表示该变量占用了 4 个字节的内存空间。

除了实例变量之外,alloc 还会为对象分配额外的空间,用于存储对象的其他信息,如 isa 指针、引用计数器等。这些额外空间的大小通常是固定的,因此可以将其添加到实例变量的大小中以计算 alloc 分配的总内存大小。

计算 alloc 内存开辟大小的公式:

alloc 内存大小 = 实例变量大小 + 额外空间大小

内存对齐

内存对齐是指将数据存储在内存中特定地址边界上的技术。对于类和结构体,内存对齐规则规定了成员变量在内存中的存储位置必须是其类型的倍数。例如,如果一个结构体包含一个 int 类型的成员变量,那么该成员变量必须存储在 4 字节对齐的地址上。

内存对齐的主要目的是提高性能。当处理器访问内存时,它通常一次读取多个字节。如果数据没有对齐,处理器需要执行额外的操作才能访问数据,从而降低性能。此外,内存对齐还可以防止不同类型的变量之间发生冲突。

Objective-C 中的内存对齐规则:

  • 对于类,所有实例变量都必须是 4 字节对齐的。
  • 对于结构体,所有成员变量都必须是其类型的倍数对齐的。

类和结构体内存对齐示例

类内存对齐示例:

假设有一个 Person 类,其中包含两个实例变量:name(类型为 NSString*)和 age(类型为 int)。

  • NSString* 类型占用了 8 字节的内存空间。
  • int 类型占用了 4 字节的内存空间。

根据内存对齐规则,name 变量必须存储在 8 字节对齐的地址上。因此,alloc 分配的内存大小为:

alloc 内存大小 = 实例变量大小 + 额外空间大小
= 8 字节(name)+ 4 字节(age)+ 额外空间大小

结构体内存对齐示例:

假设有一个 Point 结构体,其中包含两个成员变量:x(类型为 int)和 y(类型为 float)。

  • int 类型占用了 4 字节的内存空间。
  • float 类型占用了 4 字节的内存空间。

根据内存对齐规则,x 变量必须存储在 4 字节对齐的地址上,而 y 变量必须存储在 4 字节对齐的地址上。因此,alloc 分配的内存大小为:

alloc 内存大小 = 成员变量大小 + 额外空间大小
= 4 字节(x)+ 4 字节(y)+ 额外空间大小

结论

理解 Objective-C 中的 alloc 内存开辟大小和内存对齐机制对于编写高效且健壮的代码至关重要。通过遵循这些规则,可以确保对象和结构体的数据在内存中正确存储,并提高应用程序的性能。