返回

深入浅出,探秘iOS底层原理:探寻对象内存的奥秘(下)

IOS

影响对象内存的因素

决定对象内存大小的因素有以下几点:

  • 实例变量的个数和类型 :对象中实例变量的数量和类型直接影响对象的大小。例如,如果对象包含一个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底层原理有更加深入的理解。