《iOS开发进阶》第20章:Tagged Pointer对象

对于64位程序,引入Tagged Pointer后,相关逻辑能减少一半的内存使用,用有3倍的访问速度提升,以及100倍的创建、销毁速度提升。

1、原有系统的问题

假设我们要存储一个NSNumber对象,其值是一个整数。正常情况下,如果这个整数只是一个NSInteger的普通变量,那么它所占用的内存与CPU的位数有关,在32位CPU下占4个字节,在64位CPU下占用8个字节。而指针类型的大小通常也与CPU位数相关,一个指针所占用的内存在32位CPU下为4个字节,在64位CPU下是8个字节。

所以一个普通的iOS程序,如果没有Tagged Pointer对象,从32位机器迁移到64位机器中后,虽然逻辑没有任何变化,但这种NSNumber、NSDate一类的对象所占用的内存会翻倍。

效率问题:为了存储和访问一个NSNumber对象,我们需要在堆上为其分配内存,另外还要维护它的引用计数,管理它的生命周期,这些都给程序增加了额外的逻辑,造成运行效率上的损失。

2、Tagged Pointer介绍

为了改进前面提到的内存占用和效率问题,苹果提出了Tagged Pointer对象。我们可以将一个对象的指针拆分成两部分,一部分直接保存数据,另一部分作为特殊标记,表示这是一个特别的指针,不指向任何一个地址。

 

Tagged Pointer特点:

Tagged Pointer专门用来存储小的对象,例如NSNumber和NSDate。

Tagged Pointer指针的值不再是地址,而是真正的值。所以,实际上它不再是一个对象了,它只是一个披着对象“皮”的普通变量而已。所以它的内存并不存储在堆上,也不需要malloc和free。

在内存读取上有着以前3倍的效率,创建比以前快106倍。

 

3、注意事项和实现细节

3.1 isa指针,Tagged Pointer的引入也带来了问题,即Tagged Pointer并不是真正的对象,而是一个伪对象,所以如果你完全把它当成对象来使用,可能会让它露马脚。

所有对象都有isa指针,而Tagged Pointer对象是没有的,因为它不是真正的对象,所以如果直接访问Tagged Pointer的isa成员的话,在编译时会有警告。

3.2 64位下的isa指针优化。

3.3 isa的bit位含义

 

总结:

苹果引入Tagged Pointer,给64位系统带来了内存的节省和运行效率的提高。Tagged Pointer通过在其最后一个bit位设置一个特殊标记,用于将数据直接保存在指针本身中。因为Tagged Pointer并不是真正的对象,我们在使用时需要主要不要直接访问其isa变量。

本文来自Awnlab.com麦芒实验室,转载请注明出处,谢谢合作。