2014-02-19 60 views
2

我是新來obj-c開發,但部分有C開發背景。這可能是一個noob問題,但我無法在其他地方得到確切的答案。是什麼數組和字符串以及可能的其他類型的對象,這些片段之間的區別:Objective-C =運算符vs stringWithString/arrayWithArray

NSArray *original = [NSArray arrayWithObjects:someObjects,nil]; 
//Case 1 
NSArray *copy1 = original; 
//Case 2 
NSArray *copy2 = [NSArray arrayWithArray:original]; 

和字符串

NSString *original = @"aString"; 
//Case 1 
NSString *copy1 = original; 
//Case 2 
NSString *copy2 = [NSString stringWithString:original]; 

如果我更改Copy1,然後COPY2後來將他們在原來的反映對象?並且相同的規則是否適用於其他對象類型?

+0

'NSArray'和'NSString'都是理解基本指針語義和對象身份的最好例子**不創建副本**如果原始文件不能更改(是不可變的)。 –

+0

您無法更改ether copy1或copy2指向的字符串;他們是不變的。但是您可以將新值分配給copy1或copy2。 – geowar

回答

2

你的問題真的是關於什麼對象指針指向。當你說make changes to copy1 and copy2 later時,我想你的意思是指向指針的內容,而不是指向該指針引用的對象。這是一種相當有效的思維方式,但它非常重要。

在你的例子中,數組/字符串部分並不重要,因爲你沒有對對象做任何事情,你只是在做指向這些對象的指針。

original指向一個對象。 copy1指向同一個對象。 copy2指向一個不同的對象(但在這種情況下,它是第一個對象的副本)。

+1

由於原始文件是不可變的字符串,copy2不是一個不同的對象,而是完全相同的實例。 –

+0

@NikolaiRuhe,在這種情況下,是的,但我覺得這個話題很複雜。我可以擴展並考慮可變對象,如果它可以幫助 – Wain

2

第二個代碼段爲NSString做了第一個代碼段爲NSArray做了什麼。行爲沒有區別,因爲Cocoa中的NSStringNSArray對象都是不可變的

當你調用[NSString stringWithString:original],可可足夠聰明,不創建新的對象:這個決定背後的原因是,由於original無法改變,沒有什麼你可以做些什麼來分辨從原來的一個副本。 [NSArray arrayWithArray:original]也是如此,因爲你得到了相同的實例。

注意:如果someObjects是可變的,可以通過修改對象並查看它是否在其他位置發生變化來區分深拷貝中的數組。然而,arrayWithArray:方法會產生「淺」副本,所以即使數組內的對象是可變的,也無法檢測到差異。

+0

'someObjects'可變性對於'arrayWithArray'創建新實例或不是不相關。只考慮接收器。副本總是很淺。 –

+0

@NikolaiRuhe我的觀點是,如果對象是可變的,你可以知道是否有深層複製。如果它是不變的,那麼就沒有合法的方法來區分它們。 – dasblinkenlight

+0

這兩個數組(原始數組和從'arrayWithArray'返回的數組)不能分開,因爲它們是同一個實例(如果在這種情況下原始數據是不可變的)。這不取決於元素。 –

0

NSArrays和NSStrings是不可變的,所以你不能改變它們。

您不能添加或刪除NSArray中的對象,但如果您更改數組中的某個對象,它將在其副本中更改,因爲NSArray包含指向它的指針。

1

copy1不是副本,而是指向與original相同的內存的另一個指針。 copy2實際上是一個副本,指向一塊不同的內存。

如果修改copy1(假設它是可變的,您的示例代碼不是),那麼您也正在修改original,因爲它們指向相同的內存塊。

如果修改copy2original應該保持不變(一般來說)。在你的數組示例中,數組original和數組copy2中的對象是,我相信相同。所以你在這種情況下,你有兩個數組,但他們有相同的對象。

+0

'copy2'沒有指向另外一塊內存,它是同一個實例 –

+1

@NikolaiRuhe對不起,'+ arrayWithArray'返回一個新的數組,填充內容 –

+0

噢,我錯了,我的印象是'arrayWithArray:'會和'copy'做同樣的優化,感謝您指出這一點! –