[IOS 开发] NSString内存管理,NSString放在内存的什么区域

测试代码:

NSString *str1 = [NSString stringWithFormat:@"小强"];
NSString *str2 = [NSString stringWithFormat:@"1"];
NSString *str3 = [NSString stringWithFormat:@"a"];
NSString *str4 = @"123456789";

上面这段代码控制台显示为:

我们知道oc存储主要分成数据区、堆区和栈区,

  • __NSCFConstantString显然是常量字符串,自然就是存储在常量区。
  • __NSCFString表示为oc对象,NSString就是封装的CFString0x6000000315c0地址显示这个字符串对象存储在堆中。
  • NSTaggedPointerString这个类表示这是字符串的一种指针Tagged Pointer,0xa636261646362617这个地址为什么如此与众不同呢,接下来我们就简单介绍这钟字符串的存储指针。

 

在苹果的64位OC实现中,若对象指针的二进制第一位是1,则该指针为Tagged Pointer。
例如0xa000000000000311其中a的2进制为1010,第一位1表示这是Tagged Pointer,010表示这是一个NSTaggedPointerString类;这个地址最后一位表示字符串的数目,这里是0001表示有1位字符串;其中真正用来存储的位数只有中间的14位16进制。这个地址本身其实就存储了字符串的值,可以说是存储在&strS内存中值,只是伪装成了地址,它不需要存储在数据区,也不需要申请堆空间。

NSTaggedPointerString的存储有三种编码方式:ASCII码,六位编码,五位编码。

ASCII码

我们发现NSTaggedPointerString存储内容除去第一位和最后一位,其实只有中间的14位16进制字符,再看ascll码由8位二进制组成,所以这里(14*4) / 8=7,用8位的ascll码的话最多可以存储7个字符。字符串数目0~7之间

[NSString stringWithFormat:@"1"]输出的地址 0xa000000000000311,其中31的2进制是0011 0001,在ascll码表里查找发现正是对应着“1”;

[NSString stringWithUTF8String:"abcdabc"] 这里输出的地址是0xa636261646362617 可以发现在使用ascll编码时,字符串对应的编码是从右向左存储的

六位编码:

NSTaggedPointerString 采用六位二进制编码,(14*4)/6=9.333…,可以看出最多存储9位字符。字符数目8~9

五位编码:

采用五位二进制编码,(14*4)/5 = 11.2,可以看出这种编码最多存储11位字符。字符数目在10~11

NSTaggedPointerString 存储编码中的六位和五位编码都是根据通常代码中字母使用频率来排序的,但并不是一成不变的,apple会持续更新并统计字母使用频率,系统每次升级都可能不一样,当前第一位是字母e,之后是i,l,o,t…;这两种编码是从左向右的;根据编码位数我们显然也能推测出并不是所有字符都可以进行ascll或者六位五位编码的,当出现这样不能编码的时候,系统也就不会使用NSTaggedPointerString类。

 

参考:
1.Tagged Pointer Strings

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值