ToB企服应用市场:ToB评测及商务社交产业平台

标题: 内存管理(二)之别小看了Tagged-Pointer关键时刻起到大作用 [打印本页]

作者: 拉不拉稀肚拉稀    时间: 2022-9-16 17:20
标题: 内存管理(二)之别小看了Tagged-Pointer关键时刻起到大作用
本文主要研究Tagged Pointer技术,针对该技术需要解决的问题、以及在实际应用中的价值做一些简单的探讨。
如果你想要更进一步,去挖掘Tagged Pointer是如何实现的,可以参考Friday Q&A 2012-07-27: Let's Build Tagged Pointersobjc源码
另外,本文中涉及到的示例代码,请在真机iOS设备上测试,因为Tagged Pointer技术针对不同的平台,具体实现细节是有差异的,否则无法得出和本文一致的测试结果。
一、对象的内存

下面我们针对iOS中对象进行一些探究,代码如下,其完整代码见TaggedPointer
  1.     __weak NSNumber *weakNumber;
  2.     __weak NSString *weakString;
  3.     __weak NSDate *weakDate;
  4.     __weak NSObject *weakObj;
  5.     int num = 123;
  6.    
  7.     @autoreleasepool {
  8.         weakObj = [[NSObject alloc] init];
  9.         weakNumber = [NSNumber numberWithInt:num];
  10.         weakString = [NSString stringWithFormat:@"string%d", num];
  11.         weakDate   = [NSDate dateWithTimeIntervalSince1970:0];
  12.     }
  13.     NSLog(@"weakObj is %@", weakObj);
  14.     NSLog(@"weakNumber is %@", weakNumber);
  15.     NSLog(@"weakString is %@", weakString);
  16.     NSLog(@"weakDate is %@", weakDate);
复制代码
第7行,首先定义了4个__weak***对象,构建了一个autoreleasepool,所以在12行之后,所有__weak修饰的弱引用对象,都会被释放。经过上面分析,我们得出,对象会打印出null。
但是,实际上,我们得到了如下的输出。
TaggedPointer[3570:3928309] weakObj is (null)
TaggedPointer[3570:3928309] weakNumber is 123
TaggedPointer[3570:3928309] weakString is string123
TaggedPointer[3570:3928309] weakDate is Thu Jan  1 08:00:00 1970
可以看到,只有NSObject对应的对象值是null,其他的值,均正常打印。
这是因为NSNumber、NSString、NSDate,在这里采用了Tagged Pointer技术。
二、Tagged Pointer

2.1 Tagged Pointer技术

2.1.1 简介


2.2.2 未引入Tagged Pointer


2.2.3 引入Tagged Pointer


2.2.4 判断是否是Tagged Pointer


2.2 应用

2.2.1 支持的对象类型

可以从objc源码中找出支持Tagged Pointer 的对象类型,如下:
  1. typedef uint16_t objc_tag_index_t;
  2. enum
  3. {
  4.     OBJC_TAG_NSString          = 2,
  5.     OBJC_TAG_NSNumber          = 3,
  6.     OBJC_TAG_NSIndexPath       = 4,
  7.     OBJC_TAG_NSDate            = 6,
  8.     ....
  9. };
复制代码
即针对NSString、NSNumber、NSDate、NSIndexPath这些类型,都支持Tagged Pointer技术。
2.2.2 NSNumber

我们通过NSNumber以及NSString对象来观察Tag+Data的存储形式。
示例代码参见:TaggedPointer
如下所示,我们创建了很多NSNumber对象:
  1.     NSNumber *number1 = @1;                          //0xb000000000000012
  2.     NSNumber *number2 = @2;                          //0xb000000000000022
  3.     NSNumber *number3 = @(0xFFFFFFFFFFFFFFF);        //0x1c0022560
  4.     NSNumber *number4 = @(1.2);                      //0x1c0024b80
  5.     int num4 = 5;
  6.     NSNumber *number5 = @(num4);                     //0xb000000000000052
  7.     long num5 = 6;
  8.     NSNumber *number6 = @(num5);                     //0xb000000000000063
  9.     float num6 = 7;
  10.     NSNumber *number7 = @(num6);                     //0xb000000000000074
  11.     double num7 = 8;
  12.     NSNumber *number8 = @(num7);                     //0xb000000000000085
  13.    
  14.     //值:0xb000000000000012 0xb000000000000022 0x1c0022560 0x1c0024b80 0xb000000000000052 0xb000000000000063 0xb000000000000074 0xb000000000000085
  15.     NSLog(@"%p %p %p %p %p %p %p %p", number1, number2, number3, number4, number5, number6, number7, number8);
复制代码
由上表我们得出:


并且,针对以上部分,我们整理出Tagged Pointer的存储格式如下,以number1为例:

2.2.3 NSString

同上面NSNumber的处理逻辑,NSString处理的类似。
  1. NSString *str1 = @"a";                                          //0x1049cc248
  2. NSString *str2 = [NSString stringWithFormat:@"a"];              //0xa000000000000611
  3. NSString *str3 = [NSString stringWithFormat:@"bccd"];           //0xa000000646363624
  4. NSString *str4 = [NSString stringWithFormat:@"c"];              //0xa000000000000631
  5. NSString *str5 = [NSString stringWithFormat:@"cdasjkfsdljfiwejdsjdlajfl"];//0x1c02418f0
  6. NSLog(@"%@ %@ %@ %@ %@",
  7.       [str1 class],   //__NSCFConstantString
  8.       [str2 class],   //NSTaggedPointerString
  9.       [str3 class],   //NSTaggedPointerString
  10.       [str4 class],   //NSTaggedPointerString
  11.       [str5 class]);  // __NSCFString
复制代码
根据以上结果,我们将NSString分类三类:


以上,整理如下:

NSString以Tagged Pointer的存储格式如下:

2.3 内存管理




三、一个面试问题的研究
该面试题如下:



参考
链接
1Friday Q&A 2012-07-27: Let's Build Tagged Pointers
2Tagged Pointer wiki
3NSString retain count -1
4objc源码
示例代码
1TaggedPointer
青山不改,绿水常流!谢谢大家支持。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4