Nsstring定義時用copy還是用strong

1.首先定義兩個屬性

@property (nonatomic,strong)NSString  *strongStr;
@property (nonatomic,copy  )NSString  *copyssStr;

2.然後聲明一個不可變的NSSring對象,給這兩個屬性對象賦值,分別輸出他們的指針和內存地址。

- (void)test{
    NSString *string = [NSStringstringWithFormat:@"測試文字"];//註釋1
    self.strongStr = string;
    self.copyssStr = string;

    NSLog(@"測試文字   String: %p, %p", string, &string);
    NSLog(@"Strong屬性 String: %p, %p",_strongStr, &_strongStr);
    NSLog(@"Copy  屬性 String: %p, %p",_copyssStr, &_copyssStr);
}

輸出如下:

2017-08-10 15:37:57.409 text[58755:1219627] 測試文字   String: 0x7ae904f0, 0xbffd80ac
2017-08-10 15:37:57.409 text[58755:1219627] Strong屬性 String: 0x7ae904f0, 0x7cc820f0
2017-08-10 15:37:57.410 text[58755:1219627] Copy  屬性 String: 0x7ae904f0, 0x7cc820f4
(lldb) 

結果表明:不管是Strong還是Copy屬性的對象,指向的地址都是同一個原來String指向的地址。
如在MRC環境,輸出String的引用計數,會看到其引用計數值是3,即Strong操作和Copy操作都會使原字符串對象的引用計數值加了1。

3.接着再聲明一個可變的NSSring對象,給這兩個屬性對象賦值,分別輸出他們的指針和內存地址。
只替換註釋1 代碼爲以下代碼,輸出。

NSMutableString *string = [NSMutableStringstringWithFormat:@"測試文字"];

輸出如下:
2017-08-10 15:41:55.298 text[58856:1225618] 測試文字 String: 0x7d26fb40, 0xbff9c0ac
2017-08-10 15:41:55.298 text[58856:1225618] Strong屬性 String: 0x7d26fb40, 0x7d062af0
2017-08-10 15:41:55.298 text[58856:1225618] Copy 屬性 String: 0x7d274510, 0x7d062af4

結果輸出有不同:此時Copy屬性字符串已不再指向原來String對象,而是深拷貝了String字符串,且copyssString對象指向這個字符串。

在MRC環境下,輸出兩者的引用計數,可以看到String對象的引用計數是2,而copyssString對象的引用計數是1。

如果去修改String字符串的話,可以看到:因爲strongString與原始String是指向同一對象,所以strongString的值也會跟隨着改變(此時strongString的類型實際上是NSMutableString,而不是NSString);而copyssString是指向另一個對象,並不會改變。

4.最後結論

我們知道NSMutableString是NSString的子類,一個NSString指針可以指向NSMutableString對象,strongString指針指向一個可變字符串是正常的。
如上例子可以看出:

1) 當原字符串是NSString時,字符串是不可變的,不管是Strong還是Copy屬性的對象,都是指向原對象,Copy操作只是做了次淺拷貝。
2) 當原字符串是NSMutableString時,Strong屬性只是增加了原字符串的引用計數,而Copy屬性則是對原字符串做了次深拷貝,產生一個新的對象,且Copy屬性對象指向這個新的對象,且這個Copy屬性對象的類型始終是NSString,而不是NSMutableString,因此其是不可變的。

3) 這裏還有一個性能問題,即在原字符串是NSMutableString,Strong是單純的增加對象的引用計數,而Copy操作是執行了一次深拷貝,所以性能上會有所差異(雖然不大)。如果原字符串是NSString時,則沒有這個問題。

所以,在聲明NSString屬性時,到底是選擇strong還是copy,可以根據實際情況來定。不過,一般我們將對象聲明爲NSString時,都不希望它改變,所以大多數情況下,我們建議用copy,以免因可變字符串的修改導致的一些非預期問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章