2012-08-16 125 views
4

我開始了一個小的Xcode項目來調查NSMutableString屬性應該是copy還是retain。我聲明我與copy屬性屬性:試圖使用複製的NSMutableString屬性導致異常

@property (nonatomic,copy) NSMutableString *stringA; 

然後初始化它爲self.stringA = [NSMutableString new];

終於嘗試設置字符串[stringA setString:@"A"];

但是程序給出,

「終止應用程序由於未捕獲的異常‘NSInvalidArgumentException’,理由是:‘試圖改變一個不可改變的對象,具有了setString:’」

是因爲所產生的字符串是NSString?這是否意味着我應該使用retain屬性和NSString屬性使用copy來聲明我的NSMutableString屬性?

+3

你幾乎肯定不希望可變字符串作爲一個屬性在第一個地方;至少,沒有一個暴露爲API。 – bbum 2012-08-16 18:02:05

+0

我的回答太多了:http://stackoverflow.com/questions/4995254/nsmutablestring-as-retain-copy/5004019#5004019 – justin 2012-08-16 18:03:01

+0

對NSStrings使用'copy'毫無意義。 – 2012-08-16 18:03:06

回答

10

你說得對,的NSMutableStringcopy方法返回一個不變NSString。這是可可公約,它也適用於NSMutableArray,NSMutableDictionary等。

所以如果你想讓你的財產保持可變,你應該聲明它爲retain。如果您需要複製語義,但仍希望結果可變,則必須爲屬性實現自己的setter(並使用mutableCopy進行復制)。

對於字符串屬性,您通常會看到copy的原因是,通常需要保證字符串是不可變的,而不管分配給屬性的字符串是什麼類型。否則,你可能會意外地在別處修改相同的字符串,這很難調試。不可變的對象也有線程安全的好處。

+0

所以基本上我應該使用副本的NString,NSArray,NSDictionary類型,因爲有可變的變體和像NSMutableString,NSMutableArray這樣的可變類型我應該使用retain。它是否正確? – rustylepord 2012-08-16 18:06:20

-1

我會問的第一個問題是如何初始化stringA。如果你從一個普通的String中設置它,那麼它可能就是你爲什麼要這樣做的原因。複製和保留實際上表現不同,你應該知道你爲什麼要使用其中一種。

複製實際上是複製內存,以便您對該屬性所做的任何更改都不會影響從其中設置的原始內容,而僅保留增量內存的保留計數以確保它不會被釋放直到完成引用爲止。

+0

我初始化它爲self.stringA = [NSMutableString new]; – rustylepord 2012-08-16 17:55:26

+0

將其初始化爲self.stringA = [[NSMutableString alloc] init];並且看看它是否改變了什麼 – rooster117 2012-08-16 17:56:24

+4

'new'只是'alloc init'的縮寫,它們完全一樣。 – omz 2012-08-16 18:00:20