2010-11-03 90 views
3

會有人這麼好,以確認我正確理解這一點。我最初對此的迴應是,將mutableArray分配給imm​​utableArray時將成爲immutableArray,但事實並非如此。分配,可變爲不可變數組?

這是因爲初始數組被分配爲mutableArray,而immutableArray只是被分配指向同一個對象。編譯器給出警告,但代碼在運行時很好地執行。

NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"Teddy", @"Dog", nil]; 
NSArray *iArray = mArray; 
[iArray addObject:@"Snoss"]; // Normally this would crash NSArray 

大加讚賞

加里。

回答

4

不要混淆您剛剛創建物理對象,你是如何effectivley 它在你的代碼鑄造

在這種情況下,您的做了物理創建一個NSMutableArray。

然後你有效地把它轉換成一個NSArray - 這是完全有效的 - 例如,很多情況下函數可能需要一個NSArray,並且你可以將它傳遞給一個NSArray,或者從它派生的任何東西(比如NSMutableArray )。

問題是你得到一個編譯器警告,因爲你試圖調用addObject的對象,編譯器認爲只是一個NSArray,因爲這就是它的物理類型。

這實際上工作,因爲它實際上是一個NSMutableArray,並在運行時會到選擇迴應。

這樣做是不好的編碼習慣,因爲NSArray實際上不會響應addObject選擇器。例如,我可以創建一個功能,如:

-(void) addIt:(NSArray)myThing { 
    [myThing addObject:@"New String"]; 
} 

編譯器會給你一個警告,稱「NSArray的」不爲「ADDOBJECT」選擇作出迴應。如果你施放了一個NSMutableArray,並將它傳遞給這個函數,那麼myThing,它實際上工作。

雖然這是個壞習慣,因爲如果你真的通過了NSArray,它會崩潰。

摘要:不要混淆什麼對象真的是與要製作的編譯器解釋爲

+0

謝謝你一個很好的答案布拉德,非常感謝。 – fuzzygoat 2010-11-03 19:43:36

2

是的,你是對的。你應該做

NSArray *array = [NSArray arrayWithArray:mutableArray]; 

,以確保沒有人可以改變陣列

0

AFAIK,你是正確的。 NSMutableArray是NSArray的一個子類,因此您可以在這裏毫無問題地將mArray分配給iArray。

但是,它不是乾淨的代碼,你應該避免它。

1

你的iArray實際上是引用到NSMutableArray實例,這就是爲什麼它是一個NSMutableArray。

Obj-c沒有對類類型進行嚴格檢查,所有對象的類型都是'id'。 你可以寫

NSNumber *iArray = mArray 

編譯器會顯示錯誤的投(不是錯誤)的警告。但它會起作用。

不要混淆指針,沒有對象類型轉換,就像您在C++中所期望的那樣。 (有可重複的操作符將對象轉換爲另一個類)。

Obj-c與對象很像腳本/解釋型語言。動態類型(僅對象),反射,類的實例方法的動態變化等 - 充分的靈活性。低級C/C++速度與動態靈活性的完美結合。