2012-04-23 44 views
0

嗨,我得到的信息,NSString值是不可變的,一旦它提供了一個值,不能改變。是否NSString的值一旦被提供一個值就無法更改?

但我已經創建並測試了下面的代碼:

NSString *str=[[NSString alloc] initWithString:@"Hello"];  
NSLog(@"\n\nstr = %@",str); 
[email protected]"asdasd"; 
NSLog(@"\n\n new str = %@",str); 

,這給「你好」作爲第一STR值和「asdasd」作爲第二個STR值。如果是這樣,調用NSString不變的相關性是什麼?提前致謝。

回答

10

你在第三行做什麼只是創建一個新的字符串,並用str變量指向它。您沒有更改原始字符串,而是將變量指向新的字符串。

+1

並且如果您不使用ARC,可能會泄漏原始字符串。 – mttrb 2012-04-23 04:33:45

+0

@Juan:如果可以更改str的字符串值,爲什麼NSString變量被稱爲不可變,以及可變字符串和不可變字符串之間的真正區別是什麼? – 2012-04-23 04:34:34

+0

@mttrb這就是我在說我的答案... – 2012-04-23 04:35:21

4

你混淆了一個不可變對象和一個常量指針(加上你正在泄漏內存)。在這裏你並沒有真正改變NSString 實例(也就是對象本身),而只是一個指向它的指針。重點是您可以將NSString的不同實例分配給同一個變量,它不會更改對象的內部內容,也不會響應NSMutableString的突變消息,例如appendString等。

5

NSString不可改變的。你不能改變它。您的混淆源自您的變量(指針)不是const

所有你正在做的是重新指派一個不同的不可變字符串的指針。

如果您試圖將字符串追加到任一字符串,則會發生錯誤。具體來說,這是「......調用NSString不變的相關性」。您應該將此解釋爲字符串實例可能不會發生變化,即使您聲明的變量可能會被分配另一個NSString實例,因爲它不是const

可以使這兩個指針常量和字符串不變,像這樣:

NSString * const aStr = @"aStr"; 
+1

+1。另外,實際上,在CoreFoudation中,CFStringRef被聲明爲'struct __CFString * const',並且NSMutableString被聲明爲'struct __CFString *'。 – 2012-04-23 04:36:26

+1

yup - 這是他們如何在C中爲CFString類型實現一個類型化的多態聲明(儘管'const'在CFStringRef的情況下應用於* type *,而不是指針 - const struct __CFString *') – justin 2012-04-23 04:41:40

+0

是啊......看到蘋果經常不合邏輯且過度複雜的源代碼讓我哭... – 2012-04-23 04:45:15

1

使用此意願溶膠您的問題...

NSString *str=[NSString stringWithFormat:@"Hello"];  
NSLog(@"\n\nstr = %@",str); 
str = nil; 
[email protected]"asdasd"; 
NSLog(@"\n\n new str = %@",str); 

這一些基本的,你應該知道..

NSString *s1 = @"string1"; 
NSString *s2 = [[NSString alloc] initWithString:@"string2"]; 
NSString *s3 = [NSString stringWithFormat:@"string3"]; 

s1在這種情況下是一個指向常量字符串的指針。 s2和s3都指向您創建的新字符串,但s2已保留給您,並且s3已被自動發佈。如果您只需要一個臨時對象,則自動釋放對象s3或常量對象s1是很好的選擇。如果你需要保留字符串,你應該使用s2(實際上現在我認爲s1在這種情況下也會起作用 - 但它並不是真正的習慣)。

通過發送保留消息,可以使s1或s3等同於s2。你也可以通過發送一個autorelease消息來將s2變成一個等效的對象。

相關問題