2012-11-09 58 views
1

我剛剛開始,我有點掛斷了。我可能有一個基本的誤解,你可以幫助我。objective-c字符串:爲什麼你不需要setter/getter?

爲什麼你可以直接給NSString *(和,我敢肯定,許多其他對象類型)分配一個字符串值?例如,

NSString * s = @「Hello,world!」;

而下面的代碼,相信,將會分配給S2 S1的指針值(因此僅順便提供S2具有字符串值)?

NSString * s1 = @「Hello,world!」;

NSString * s2 = s1;

對於很多對象,您是否需要指定要爲其指定值(即,使用setter方法)的屬性a.k.a.實例變量?對象本身不應只接受指針值的賦值嗎?或者像NSString這樣的類自動重新解釋代碼,例如上面的第一個例子,使用隱含的setter將指定的字符串賦給一個隱含的實例變量?

+2

字符串很常見,通常在編程語言中給予特殊處理。 – nhahtdh

+0

除了Perception的回答,你可能想看看[這裏](http://gcc.gnu.org/onlinedocs/gcc/Constant-string-objects.html)關於如何在ObjC中處理常量字符串的更多信息。 – Ephemera

+0

謝謝,所有這些回覆都很有幫助,但我還是沒有被允許投票。 – mkc842

回答

3

爲什麼你可以直接給NSString *(以及我確定是很多其他對象類型)賦值一個字符串值?

儘管看起來像它,但您並未將字符串'值'直接賦值給實例變量。實際上,您將字符串值的地址分配給您的實例變量。現在,真正的問題是,到底是怎麼回事幕後時,你有類型的表達式:

NSString * str = @"Hello World"; 

該表達式表示一個字符串字面的創建。在C語言(以及Objective-C是C的嚴格超集)中,字符串文字會得到特殊的處理。具體而言,會發生以下情況:

  1. 當你的代碼被編譯字符串「Hello World」將在 程序中的數據部分來創建。
  2. 當程序執行時,實例變量'str'將被分配到堆上。
  3. 'str'實例變量將指向存儲實際字符串「Hello World」的靜態內存位置。

您的第一個和第二個示例的主要區別在於,在第二個示例中,字符串變量的內存在運行時在堆上動態分配。請注意,在這兩種情況下,變量'str'只是一個動態分配的指針。

0

這是編譯器的功能,而不是語言結構。在這種情況下,編譯器識別字符串文字並插入一些代碼以產生預期的結果。

@「」實質上是NSString的+ stringWithUTF8String方法的簡寫。

採取從這裏: What does the @ symbol represent in objective-c?

1

更多或更少的後者。字符串文字如@"Hello World!"在Objective-C中被視爲一種特殊情況:使用該語法聲明的字符串在編譯時被靜態分配,實例化和緩存以提高性能。從程序員的角度來看,與調用[NSString stringWithString:@"Hello World!"]或使用C字符串的構造函數沒有什麼不同 - 您應該將其視爲語法糖。

FWIW Objective-C最近開始擴展@前綴以允許聲明字典和數組文字,例如:@{ @"key" : @"value" }@[ obj1, obj2, obj3 ]

0
NSString *s1 = @"Hello, world!"; 

基本上等同於

NSString *s1 = [NSString stringWithUTF8String:"Hello, world!"]; 

前者靜態分配一個新的NSString對象(而不是在運行時的堆,因爲後者會做)。

重要的是要指出,這些只是指針。當您執行NSString *s2 = s1時,s1s2都引用同一個對象。

+1

這是不正確的。字符串文字不分配在堆上。 – Perception

+0

對不起,誤讀了一些東西。你是對的。 –

相關問題