本文转载自http://www.cnblogs.com/celestial/archive/2012/10/10/2719169.html html
一切权力归原做者全部,并在此向原做者表示感谢。 xcode
生成一个NSString类型的字符串有三种方法: 函数
方法1.直接赋值: NSString *testStr1 = @"a"; 优化
方法2.类函数初始化生成: spa
NSString *testStr2 = [NSString stringWithString:@"b"]; debug
NSString *testStr3 = [NSString stringWithFormat:@"c"]; code
方法3.实例方法初始化生成: orm
NSString *testStr4 = [[NSString alloc] initWithString:@"d"]; htm
NSString *testStr5 = [[NSString alloc] initWithFormat:@"e"]; blog
首先查看它们的地址和引用计数:
2012-10-11 17:35:25.601 StringDemo[8514:11303] test1Address:0x4698
2012-10-11 17:35:25.601 StringDemo[8514:11303] test2Address:0x46a8
2012-10-11 17:35:25.602 StringDemo[8514:11303] test3Address:0x746c820
2012-10-11 17:35:25.602 StringDemo[8514:11303] test4Address:0x46c8
2012-10-11 17:35:25.603 StringDemo[8514:11303] test5Address:0x7455990
2012-10-11 17:35:25.585 StringDemo[8514:11303] test1:4294967295
2012-10-11 17:35:25.586 StringDemo[8514:11303] test2:4294967295
2012-10-11 17:35:25.596 StringDemo[8514:11303] test3:1
2012-10-11 17:35:25.600 StringDemo[8514:11303] test4:4294967295
2012-10-11 17:35:25.600 StringDemo[8514:11303] test5:1
从上能够看出,test1,test2,test4都是在一个内存区域,也就是上文所说的常量内存区。test3,test5在一个内存区,也就是堆区。
这里就有一个疑问:[NSString alloc] initWithString:@"d"这种方式初始化的字符串,也就是test4.应该是位于堆区的,但为何会跑到常量内存区来呢?听说是由于xcode对这种方式作了处理,还包括[NSString stringWithString:@"b"]这种方式,这两种初始化字符串都等同于@"ddd"了。因此说test2,test4都同等于test1了。
还有,对于NSString *testStr3 = [NSString stringWithFormat:@"c"];这种初始化的字符串,只要一写release语句就会挂掉,但其它的都不会挂掉,test1,test2,test4好理解,由于release原本就不会起做用;但testStr5不管release多少次也不会挂掉,只会在控制台报警告:malloc: *** error for object 0x744d650: double free*** set a breakpoint in malloc_error_break to debug。这个猜想应该是也xcode作了优化吧。
对如今4.4以后的编译器,NSString *testStr2 = [NSString stringWithString:@"b"];这种写法会报警告了:Using 'stringWithString' with a literal is redundant。也就是说这种写法是多余的了,它给的建议是用=@"b"这种方式来代替了。
小结下吧:
对NSString的初始化方法,对于test1,test2,test4这三种的话建议用=@“字符串”来使用,由于原本就是同样的。test3,test5这两种的话,建议用texst3这种,方便点,不用管内存问题,系统自已管理。