关于TaggedPoiner中字符排列的一些探究(疑惑)
内容提要
这篇文章探讨了TaggedPointer中字符排列的规律。文章通过实验和分析发现,TaggedPointer中的字符数量小于等于7时是倒序排列,大于7时是正序排列。此外,小于等于7的字符有距离,而大于7的字符没有距离。文章提出了三个疑问,即为什么规则不一致以及为什么没有直接使用ASCII编码。作者希望有人能解答这些问题。
延伸解读
实验前提:关闭混淆才能观察原始位模式
文章指出,要直接查看TaggedPointer的原始位模式,必须在Xcode的Scheme中设置环境变量OBJC_DISABLE_TAG_OBFUSCATION = YES。否则打印出的地址是经过混淆的乱码,无法分析其编码规律。这一设置是后续所有观察的基础,也提醒读者:日常开发中看到的TaggedPointer地址并非其真实内存表示,而是经过安全处理后的结果。
编码规则的分界点:7字符与8字符的差异
文章通过实验发现,NSString的TaggedPointer在字符数不超过7时,字符按ASCII码倒序排列且字符间有00间隔;超过7时,字符正序排列且无间隔,但使用的编码并非ASCII。这一分界点导致两种截然不同的编码方式,作者对此提出疑问,认为统一规则或许也能表示,但实际实现却选择了不一致的方案。
非ASCII编码表:字符与存储值的映射关系
对于8位及以上字符,文章通过分析“00000000”到“99999999”的TaggedPointer,整理出每个数字字符实际存储的6位序列。这些序列与标准ASCII码完全不对应,例如字符“0”的ASCII为48,但存储值为29。作者推测可能存在一张映射表或特定转换规则,但未找到相关文档,这增加了理解TaggedPointer内部机制的难度。
未解之谜:规则不一致与编码选择的原因
文章最后提出三个疑问:为何字符数≤7时倒序排列而>7时正序?为何≤7时有间隔而>7时无间隔?为何>7时不直接使用ASCII编码?作者认为这些不一致可能是有意设计,但缺乏官方解释。这些问题反映了TaggedPointer实现中的黑盒特性,也提示开发者在依赖其内部布局时需谨慎,因为未来版本可能调整。
Q&A
TaggedPointer中字符排列的规律是什么?
字符数量小于等于7时为倒序排列,大于7时为正序排列。
为什么小于等于7的字符有距离,而大于7的字符没有距离?
文章提出了这个疑问,但没有给出明确的答案。
TaggedPointer的前缀和后缀有什么特定含义?
前缀的第一位表示是否为TaggedPointer,后缀的最后四位表示字符个数。
TaggedPointer中字符数量大于7时的编码问题是什么?
字符数量大于7时,使用非ASCII编码且没有距离,文章对此提出疑问。
如何验证TaggedPointer中字符的排列方式?
可以通过打印地址和分析二进制位来验证字符的排列方式。
TaggedPointer最多能表示多少个字符?
TaggedPointer最多能表示9个字符。