先看看我们遇到的问题
从上面运行代码所占用内存来看,并不像我们想的那样内存飚升。这是为什么?看看下面的分析:
内存地址的比较
测试用例
NSString *str1 = @"123456";
NSString *str2 = @"123456";
NSString *str3 = [NSString stringWithFormat: @"123456"];
NSString *str4 = [[NSString alloc] initWithFormat: @"123456"];
NSString *str5 = [[NSString alloc] initWithString: @"123456"];
NSString *str6 = @"123";
NSLog(@"%p", str1); // 0x100001268
NSLog(@"%p", str2); // 0x100001268
NSLog(@"%p", str3); // 0x36353433323165
NSLog(@"%p", str4); // 0x36353433323165
NSLog(@"%p", str5); // 0x100001268
NSLog(@"%p", str6); // 0x100001288
结果分析:
1. 对于str1,str2它们使用直接赋值的方式进行初始化,内容相同,所以str1和str2指向相同的内存空间。
2. 对于str3,str4它们属于同一种初始化方式,内容相同,所以str3,str4指向了相同的内存空间。
3. 对于str1/str2和str3/str4,这是两类初始化方式,自然占用空间类型不同,输出的地址不同。
4. 对于str1/2和str5,OC建议把str5的初始化方式改为直接赋值的方式,说明这两类是同一种初始化方式。占用常量内存区。
5. 通过str6,它的内容不同,自然和str1/str2/str5地址不同。
引用计数
测试用例
NSString *str1 = @"123456";
NSString *str2 = [NSString stringWithFormat: @"123456"];
NSLog(@"%lu", [str1 retainCount]); // 18446744073709551615
NSLog(@"%lu", [str2 retainCount]); // 18446744073709551615
结果分析:
1. 对于第一句输出,这是很大的数字。str1指向的是静态区的内存,这里的内存不归我们管理,这个数字不必计较。
2. 对于第二句输出,它和第一句相同。这就说明了,OC的字符串压根就不需要我们去管理内存。
结论
对于NSString对象,相同内容的字符串在相同初始化方式下,只会占用一块内存。