本文轉載自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這種,方便點,不用管內存問題,系統自已管理。