内存管理(二)Tagged-Pointer
00 分钟
2020-10-2
2020-10-2
type
status
date
slug
summary
tags
category
icon
password
本文主要研究Tagged Pointer技术,针对该技术需要解决的问题、以及在实际应用中的价值做一些简单的探讨。
如果你想要更进一步,去挖掘Tagged Pointer是如何实现的,可以参考Friday Q&A 2012-07-27: Let's Build Tagged Pointersobjc源码
另外,本文中涉及到的示例代码,请在真机iOS设备上测试,因为Tagged Pointer技术针对不同的平台,具体实现细节是有差异的,否则无法得出和本文一致的测试结果。

一、对象的内存

下面我们针对iOS中对象进行一些探究,代码如下,其完整代码见TaggedPointer
第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,其他的值,均正常打印。
这是因为NSNumberNSStringNSDate,在这里采用了Tagged Pointer技术。

二、Tagged Pointer

2.1 Tagged Pointer技术

2.1.1 简介

notion image

2.2.2 未引入Tagged Pointer

notion image

2.2.3 引入Tagged Pointer

notion image

2.2.4 判断是否是Tagged Pointer

notion image

2.2 应用

2.2.1 支持的对象类型

可以从objc源码中找出支持Tagged Pointer 的对象类型,如下:
即针对NSStringNSNumberNSDateNSIndexPath这些类型,都支持Tagged Pointer技术。

2.2.2 NSNumber

我们通过NSNumber以及NSString对象来观察Tag+Data的存储形式。
示例代码参见:TaggedPointer
如下所示,我们创建了很多NSNumber对象:
由上表我们得出:
  • 很大的数字,超过Tagged Pointer表示上限的时候,将会转为对象存储,存放在堆上;
  • 如果是含有小数点的浮点数,将会直接以对象方式存储;
  • 其余类型的数字,包括不含小数部分的浮点型和整型都会以Tagged Pointer存储。
并且,针对以上部分,我们整理出Tagged Pointer的存储格式如下,以number1为例:
notion image

2.2.3 NSString

同上面NSNumber的处理逻辑,NSString处理的类似。
根据以上结果,我们将NSString分类三类:
  • 常量类型:__NSCFConstantString,定义的字符串常量。
  • Tagged Pointer类型:NSTaggedPointerString,通过对象方法创建的短字符串。
  • NSString对象类型:__NSCFString,包括NSString、NSMutableString等创建的字符串对象。
以上,整理如下:
notion image
NSString以Tagged Pointer的存储格式如下:
notion image

2.3 内存管理

notion image

三、一个面试问题的研究

该面试题如下:
notion image

参考

链接

  1. Friday Q&A 2012-07-27: Let's Build Tagged Pointers
  1. Tagged Pointer wiki
  1. NSString retain count -1
  1. objc源码

示例代码

  1. TaggedPointer