一、NSString
的三种类型
NSString *firstString = @"helloworld";
NSString *secondString = [NSString stringWithFormat:@"helloworld"];
NSString *thirdString = @"hello";
NSString *fourthSting = [NSString stringWithFormat:@"hello"];
NSLog(@"%p %@\n%p %@\n%p %@\n%p %@\n",firstString,[firstString class],secondString,[secondString class],thirdString,[thirdString class],fourthSting,[fourthSting class]);
//打印结果
2023-02-02 15:45:17.821631+0800 DJDemo[9021:376188] 0x1083bc280 __NSCFConstantString
0x6000005ccea0 __NSCFString
0x1083bc2a0 __NSCFConstantString
0xebfed946f05f65df NSTaggedPointerString
1.__NSCFConstantString
通俗理解其就是常量字符串,是一种编译时常量
这种对象存储在字符串常量区。
通过打印起 retainCount
的值,发现很大,2^64 - 1,测试证明对其进行 release
操作时,retainCount
不会产生任何变化是创建之后便无法释放掉的对象。
当我们使用不同的字符串对象进行创建时当内容相同,其对象的地址也相同,这也就证明了常量字符串是一种单例。
这种对象一般通过字面值 @"…"
、CFSTR("…")
(一种宏定义创建字符串的方法)或者 stringWithString: `方法(现在会报警告⚠️这个方法等同于字面值创建的方法)。
2.__NSCFString
和 __NSCFConstantString
不同, __NSCFString
对象是在运行时创建的一种 NSString
子类,他并不是一种字符串常量。所以和其他的对象一样在被创建时获得了 1 的引用计数。
这种对象被存储在堆上。
通过 NSString
的 stringWithFormat
等方法创建的 NSString
对象一般都是这种类型。
如果字符串长度大于 9 或者如果有中文或其他特殊符号(可能是非 ASCII 字符)存在的话则会直接成为 __NSCFString
类型。
3.NSTaggedPointerString
标签指针的概念
理解这个类型,需要明白什么是标签指针,这是苹果在 64 位环境下对 NSString
、NSNumber
等对象做的一些优化。
简单来讲可以理解为把指针指向的内容直接放在了指针变量的内存地址中,因为在 64 位环境下指针变量的大小达到了 8 字节足以容纳一些长度较小的内容。于是使用了标签指针这种方式来优化数据的存储方式。
从其的引用计数可以看出,这也是一个释放不掉的单例常量对象。当我们使用不同的字符串对象进行创建时当内容相同,其对象的地址也相同。在运行时根据实际情况创建。
对于 NSString
对象来讲,当非字面值常量的数字,英文字母字符串的长度小于等于 9 的时候会自动成为 NSTaggedPointerString
类型。(小于等于9这个数据也是原博主进行猜测,经过测试在字符串含有 q 的时候是小于等于7)
网友评论