原文?
廢話不多說症脂,原文文字描述的非常詳細句占,本文重在代碼實現,及個人觀點總結溪胶。
1搂擦、NSString屬性什么時候用copy,什么時候用strong?
這一點我的想法沒有什么出彩的地方就直接copy一下原話:
由于NSMutableString是NSString的子類哗脖,所以一個NSString指針可以指向NSMutableString對象盾饮,讓我們的strongString指針指向一個可變字符串是OK的。而上面的例子可以看出,當源字符串是NSString時丘损,由于字符串是不可變的普办,所以,不管是strong還是copy屬性的對象徘钥,都是指向源對象衔蹲,copy操作只是做了次淺拷貝。
當源字符串是NSMutableString時呈础,strong屬性只是增加了源字符串的引用計數舆驶,而copy屬性則是對源字符串做了次深拷貝,產生一個新的對象而钞,且copy屬性對象指向這個新的對象沙廉。另外需要注意的是,這個copy屬性對象的類型始終是NSString臼节,而不是NSMutableString撬陵,因此其是不可變的。
這里還有一個性能問題网缝,即在源字符串是NSMutableString巨税,strong是單純的增加對象的引用計數,而copy操作是執(zhí)行了一次深拷貝粉臊,所以性能上會有所差異草添。而如果源字符串是NSString時,則沒有這個問題扼仲。
所以远寸,在聲明NSString屬性時,到底是選擇strong還是copy屠凶,可以根據實際情況來定而晒。不過,一般我們將對象聲明為NSString時阅畴,都不希望它改變倡怎,所以大多數情況下,我們建議用copy贱枣,以免因可變字符串的修改導致的一些非預期問題监署。
關于字符串的內存管理,還有些有意思的東西纽哥,可以參考NSString特性分析學習钠乏。
這里跳轉的一篇博文非常有意思,主要說明的就是NSString初始化是調用的方法春塌,導致生成的變量內存地址問題晓避,和本文的copy簇捍、strong有異曲同工之妙。
再說一句廢話俏拱,一般情況下暑塑,對于代碼里面的變量NSString,我們并不需要淺拷貝锅必,而且在代碼邏輯不嚴謹的時候會出現各種各樣奇怪的問題事格,所以更贊成copy。
帖一段代碼:
@interface TestStringClass ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
@end
調用:
- (void)test {
NSString *string = [NSString stringWithFormat:@"abc"];
self.strongString = string;
self.copyedString = string;
NSLog(@"origin string: %p, %p", string, &string);
NSLog(@"strong string: %p, %p", _strongString, &_strongString);
NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
}
結果:
origin string: 0x7fe441592e20, 0x7fff57519a48
strong string: 0x7fe441592e20, 0x7fe44159e1f8
copy string: 0x7fe441592e20, 0x7fe44159e200
分析:
strong和copy屬性的對象搞隐,其指向的地址都是同一個驹愚,即為string指向的地址。如果我們換作MRC環(huán)境劣纲,打印string的引用計數的話逢捺,會看到其引用計數值是3,即strong操作和copy操作都使原字符串對象的引用計數值加了1癞季。
把string由不可變改為可變對象:
NSString *string = [NSString stringWithFormat:@"abc"];改為->
NSMutableString *string = [NSMutableString stringWithFormat:@"abc"];
結果:
origin string: 0x7ff5f2e33c90, 0x7fff59937a48
strong string: 0x7ff5f2e33c90, 0x7ff5f2e2aec8
copy string: 0x7ff5f2e2aee0, 0x7ff5f2e2aed0
copy屬性字符串已不再指向string字符串對象劫瞳,而是深拷貝了string字符串,并讓_copyedString對象指向這個字符串余佛。在MRC環(huán)境下,打印兩者的引用計數窍荧,可以看到string對象的引用計數是2辉巡,而_copyedString對象的引用計數是1。
這就是一般代碼的邏輯蕊退,所以說copy很適合
一般人