目录展开

在当前 Apple Foundation 类簇中,某些系统上可观察到的 NSString 具体类名包括 __NSCFConstantString、__NSCFString 和 NSTaggedPointerString;这些都是私有实现名,不能把它们当成稳定的 “三种实现方式”。
1._ _NSCFConstantString (字面量字符串)
从字面意思上可以理解为常量字符串。字符串字面量在编译时确定,例如 NSString *str = @“Hello, World!”;它们通常位于只读 Mach-O 映像区域,内容不可变,但运行时加载地址及对象是否复用都不是公开保证。其特点如下:
内存特性:字符串字面量通常位于只读 Mach-O 映像区域;实际加载地址可能随 ASLR 变化。
创建方式:使用字符串字面量 如 @“Hello” 创建的字符串。
内容相同的字符串字面量是否复用同一对象或地址不是公开保证;比较字符串内容应使用 isEqualToString:。
字符串字面量的内存由程序映像管理,不应手动 release;这不意味着它按 “单例模式” 创建。
NSString* str1 = @"iOS";官方解释:在计算机科学中,字面量(literal)是用于表达源代码中一个固定值的表示法(notation)。几乎所有计算机编程语言都具有对基本值的字面量表示,诸如:整数、浮点数以及字符串;而有很多也对布尔类型和字符类型的值也支持字面量表示;还有一些甚至对枚举类型的元素以及像数组、记录和对象等复合类型的值也支持字面量表示法。 说人话就是 代码中直接写出的固定值,是编译时可知、不可变的常量,比如数字、字符串、布尔值、数组等,具有 “所见即所得” 的特性。例如上述的语句,@“iOS” 为子面量, str 为变量
2._ _NSCFString
__NSCFString 是部分 Apple Foundation 系统中可观察到的私有类簇实现名。stringWithFormat: 等方法返回的 NSString 具体类会随内容、系统版本和优化变化,不能把该类名当成稳定保证;也不能仅凭具体类名判断对象的公开可变性。
不能推断两次创建的相同内容字符串必定有不同内存地址;对象身份是否相同不是公开保证,判断文本相等应调用 isEqualToString:。
该底层下的不可变声明:
NSString *str2 = [NSString stringWithFormat:@"hello %d", 123];NSLog(@"%@", [str2 class]); // 输出:__NSCFString可变声明如下:
NSMutableString *mStr = [NSMutableString stringWithString:@"abc"];NSLog(@"%@", [mStr class]); // 输出:__NSCFString3.NSTaggedPointerString
在某些系统上,满足运行时内部条件的短字符串可能使用 Tagged Pointer,将类型和值编码在指针中,而不分配普通堆对象。触发长度、字符集及具体实现并非稳定公开规则。
NSString *str2 = [NSString stringWithFormat: @"%c%c%c", 'i', 'O', 'S'];Tagged Pointer 是一种运行时优化:类型和值直接编码在指针值中,因此不对应普通堆分配对象本体;具体编码和阈值属于实现细节。64 位系统上的指针宽度为 8 字节,不是 8 位;Tagged Pointer 也不是 “单例常量对象”。

附上实例一个⬆️
原文发布于 CSDN:NSString 的三种实现方式