
NSString 内存
NSString 的 几种类型
- __NSCFConstantString Constant [ˈkɑːnstənt] 常量,常数
- NSTaggedPointerString
- __NSCFString
实例代码
#import <malloc/malloc.h> // 引用头文件
#define StrLog(_c) NSLog(@"引用计数:%@ -- 堆中实际分配: %zd -- 地址:%p -- 类型:%@",[_c valueForKey:@"retainCount"], malloc_size((__bridge const void *)(_c)), _c, [_c class]);
NSString *str1 = @"123456789"; // __NSCFConstantString
StrLog(str1);
NSString *str2 = @"1234567890"; // __NSCFConstantString
StrLog(str2);
NSString *str3 = @"12345678901212345678901212345678901212345sasasa"; // __NSCFConstantString
StrLog(str3);
NSString *str4 = [NSString stringWithFormat:@"123456789"]; // NSTaggedPointerString
StrLog(str4);
NSString *str5 = [NSString stringWithFormat:@"1234567890"]; // __NSCFString
StrLog(str5);
NSString *str6 = [NSString stringWithFormat:@"12345678901212345678901212345678901212345sasasa"]; // __NSCFString
StrLog(str6);
打印结果
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x10b3f3f00 -- 类型:__NSCFConstantString
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x10b3f3f60 -- 类型:__NSCFConstantString
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x10b3f3f80 -- 类型:__NSCFConstantString
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x953b7922756a4456 -- 类型:NSTaggedPointerString
引用计数:2 -- 堆中实际分配: 32 -- 地址:0x600002545880 -- 类型:__NSCFString
引用计数:2 -- 堆中实际分配: 80 -- 地址:0x600000625ea0 -- 类型:__NSCFString
1、引用计数器的值为18446744073709551615,即为2^64-1,当引用计数器的值为-1或者无穷大的时候,说明不满足内存管理法则,既系统并不是通过内存黄金法则来释放的。也就是对str10进行retain,release操作都是没有用的。
2、str10对象在堆中实际没有分配空间,只有存放在堆区中的对象才满足内存管理法则。
3、str10对象的地址是低地址,排除代码区和常量区,所以我猜测__NSCFConstantString类型的对象存放在 初始化过的静态区:data段,继续往下走我们会验证这一猜想。

引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x103883f00 -- 类型:__NSCFConstantString
(lldb) p/x str1
(__NSCFConstantString *) $0 = 0x0000000103883f00 @"123456789"
(lldb) p/x str1->isa
(Class) $1 = 0x00000001050ed5c0 __NSCFConstantString


- 0~8 字节---> C0 D5 0E 05 01 00 00 00 isa指针
- 9~16 字节--> C8 07 00 00 00 00 00 00 一脸懵逼 8个字节可能会存放字符串的编码方式,以及对象类型
- 17~24 字节-> 53 8A 87 03 01 00 00 00 看起来像个地址
- 25~32字节-> 09 00 00 00 00 00 00 00 09
打印 0x0000000103878a53 的地址

0x10387110e
1、__NSCFConstantString类型的对象是特殊对象。其特殊性体现在可以用static修饰,存放在data段,不满足内存管理法则。
2、所有@"....."都会在内存中生成__NSCFConstantString类型的对象。
3、__NSCFConstantString类型的对象在内存中占用32个字节,用来存放isa指针,(编码形式,对象类型),字符串常量的地址以及字符串长度。
4、字符串的值(字符串常量)存放在文字常量区。
NSString *str7 = [[NSString alloc] initWithString:@"222222222222222222222"];
StrLog(str7);
// Using 'initWithString:' with a literal is redundant
NSString *str8 = [NSString stringWithString:@"2222222222222222"];
StrLog(str8);
// Using 'stringWithString:' with a literal is redundant
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x10b12efa0 -- 类型:__NSCFConstantString
引用计数:18446744073709551615 -- 堆中实际分配: 0 -- 地址:0x10b12efc0 -- 类型:__NSCFConstantString
上边也是 静态区
但是 stringWithFormat 不一样,因为可以拼接 所以 字数少的情况下 放到栈上的 NSTaggedPointerString,字数多的情况下,放到堆上的 __NSCFString
NSString 类簇
继承关系
__NSCFConstantString -> __NSCFString -> NSMutableString -> NSString -> NSObject
NSTaggedPointerString -> NSString -> NSObject
https://www.jianshu.com/p/a5b6e5838b0a
https://www.jianshu.com/p/640f173b5583




近期评论