Tagged Pointer初见

2018-03-29  本文已影响0人  Emiya_zhang

1.前言

在学习ARC机制的时候,在retain代码中

- (id)retain {
    return ((id)self)->rootRetain();
}
inline id objc_object::rootRetain()
{
    if (isTaggedPointer()) return (id)this;
    return sidetable_retain();
}

看到了如下的代码

if (isTaggedPointer()) return (id)this;

首先会判断是否是Tagged Pointer,是的话将不做处理,那么就很好奇这个神秘的指针了。

2.NSNumber中的TaggedPointer

Tagged Pointer是一个能够提升性能、节省内存的有趣的技术,苹果公司基于这两方面考量推出了这一技术。

一般来说,64位机器在没有Tagged Pointer技术的情况下

NSNumber * test = @1;

将有两部分内存占用,一个是储存‘1’的NSNumber对象,储存一个NSInteger数值8字节,一个是NSNumber指针8字节。这样来说将会出现16字节的内存占用。但是很显然大部分情况下,我们常见的整型值用四个字节都基本够用了。在处理NSNumber时便是如此,我们运行以下代码时

NSNumber * test = @1;
NSLog(@"NSp is %p ,%@",test ,test);
test = @2;
NSLog(@"NSp is %p ,%@",test ,test);
test = @(0xCFFFFFFFFFFFFFFF);
NSLog(@"NSp is %p ,%@",test ,test);

控制台输出如下

2018-03-29 20:33:00.052755+0800 CLASS1[13338:596818] NSp is 0xb000000000000012 ,1
2018-03-29 20:33:00.054739+0800 CLASS1[13338:596818] NSp is 0xb000000000000022 ,2
2018-03-29 20:33:00.056193+0800 CLASS1[13338:596818] NSp is 0x6080000369c0 ,14987979559889010687

我们可以看到0xbxxxxxxxxxxx2的格式,这个时候我们大概可以做出一个推论,对于NSInteger数值,NSNumber指针中藏了自己的对象,只有接近或大于8字节能表示的值(明天有时间写个小程序测试下)时候才会真正地生成NSNumber对象,这一角度看这的确是很好的节省方法。

特点:

  1. Tagged Pointer专门用来存储小的对象,例如NSNumberNSDate
  2. Tagged Pointer指针的值不再是地址了,而是真正的值。所以,实际上它不再是一个对象了,它只是一个披着对象皮的普通变量而已。所以,它的内存并不存储在堆中,也不需要malloc和free。
  3. 在内存读取上有着3倍的效率,创建时比以前快106倍。

备注:在WWDC2013的《Session 404 Advanced in Objective-C》视频中介绍。

3.在NSString中的TaggedPointer

请看【采用Tagged Pointer的字符串】,翻译的很棒,原文【Friday Q&A 2015-07-31: Tagged Pointer Strings

囫囵吞枣有空还要细读,无力拙劣复述了。

上一篇 下一篇

猜你喜欢

热点阅读