iOS底层探索 - 理解Tagged Pointer

765 阅读2分钟

Tagged Pointe

2013年9月苹果推出iPhone5s,iPhone5s配备首个64位架构处理器。正常情况下,数据类型所占字节数与CPU位数息息相关,例如一个NSNumber对象,在32位CPU下数据占用4个字节,指向它的指针类型也是4个字节,固创建一个NSNumber对象要占用8个字节;在64位下,数据要占用8个字节,指针也是8个字节,如果没有特殊处理,创建NSNumber对象要占用16个字节,比之前内存翻了2倍。而实际上,32位的内存就可以表示20多亿(2^31)之内的数值,剩余的空间实际上都造成了浪费。

苹果为了改善上面提到的内存占用和效率问题推出了Tagged Pointer,对于NSString、NSNumber、NSDate之类数据较小的类型变量,将其对象的指针拆分成两部分,一部分存数据,另一部分是特殊标记,表示该指针不会指向其他地址,并存储了真正类信息的索引。当不够存数据时,会动态分配内存进行存储,维护引用计数,指针存储对象地址值。

优势

引入Tagged Pointer,由于不需要再另外管理内存,直接从指针提取数据,所以在内存管理和创建上都有了较大的提升,但需要注意的是,对于Tagged Pointer类型对象是不存isa指针,所以当使用->isa时会报错,要尽量避免直接访问,而是使用isKindOfClassobject_getClass来获取类对象。

objc_msgSend与Tagged Pointe

在objc_msgSend中,Tagged Pointe对象会被特殊处理,从标识中的索引找到真正的类信息,其中系统类型的索引在高4位,拓展类型在第52~59位中。

深入理解 Tagged Pointer