返回
深入浅出,探秘iOS底层原理:探寻对象内存的奥秘(下)
IOS
2023-09-04 06:51:12
影响对象内存的因素
决定对象内存大小的因素有以下几点:
- 实例变量的个数和类型 :对象中实例变量的数量和类型直接影响对象的大小。例如,如果对象包含一个
int
类型的实例变量,则该变量在内存中将占用4个字节的空间;如果对象包含一个double
类型的实例变量,则该变量将占用8个字节的空间。 - 对齐方式 :编译器通常会对对象中的数据进行对齐操作,以提高内存访问的效率。对齐方式是指在内存中将数据存储在特定地址的倍数位置。例如,如果编译器将数据对齐到4个字节的倍数位置,则该数据将存储在4的倍数地址上。对齐方式会影响对象的大小,因为编译器可能会在对象中插入额外的字节来满足对齐要求。
- 继承 :如果对象是通过继承派生的,则其内存大小还包括基类和父类的内存大小。例如,如果对象是从
NSObject
类派生的,则其内存大小将包括NSObject
类和其父类的内存大小。 - 内存布局 :编译器还可以根据对象的类型和结构来调整对象在内存中的布局,以优化内存的使用。例如,编译器可能会将对象的实例变量存储在连续的内存地址上,或者将对象的数据成员存储在不同的内存地址上。内存布局也会影响对象的大小,因为编译器可能会在对象中插入额外的字节来优化内存的使用。
对象的内存分布
对象在内存中的分布通常分为以下几个部分:
- 实例变量区 :存储对象实例变量的内存区域。
- 继承区 :存储对象基类和父类的内存区域。
- isa指针区 :存储指向对象所属类对象的指针的内存区域。
- 非指针isa区 :存储对象类型标志的内存区域。
- 对齐字节区 :存储用于对齐对象数据而插入的额外字节的内存区域。
位域和联合体
位域和联合体是C语言中用于优化内存使用的两种特殊数据类型。
- 位域 :位域允许程序员在内存中按位存储数据,而不是按字节存储。这样可以节省内存空间,因为程序员可以将多个位域存储在同一个字节中。
- 联合体 :联合体允许程序员将不同类型的数据存储在同一个内存地址上。这样可以节省内存空间,因为程序员可以使用同一个内存地址来存储多个数据。
nonPointerisa
nonPointerisa
是iOS中用于优化内存使用的特殊机制。nonPointerisa
允许对象将isa指针和类型标志存储在同一个内存地址上。这样可以节省内存空间,因为对象不需要使用两个独立的内存地址来存储isa指针和类型标志。
如何利用isa的位运算得到类对象
isa指针是一个指向对象所属类对象的指针。我们可以通过对isa指针进行位运算来得到类对象。
Class objectClass = objc_getClass((id)object_getClass(object));
new方法
new
方法是用于创建对象的类方法。new
方法实际上是调用对象的alloc
方法和init
方法的组合。
id object = [[objectClass alloc] init];
总结
本文深入剖析了影响对象内存的因素,详细阐述了对象的内存分布,并深入探究了位域和联合体nonPointerisa,以及如何利用isa的位运算来获取类对象和new方法的原理。通过阅读本文,您将对iOS底层原理有更加深入的理解。