2009-09-22 17 views
7

假設你有一個方法返回一個新生成的NSArray實例,它內部構建了一個NSMutableArray。你總是做這樣的事情:您在Objective-C中的返回類型有多小心?

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return [NSArray arrayWithArray:mutableArray]; // .. or [[mutableArray copy] autorelease] 
} 

或者你只是離開了可變數組對象,是直接返回,因爲NSMutableArray的是NSArray中的一個子類:

- (NSArray *)someArray { 
    NSMutableArray *mutableArray = [[NSMutableArray new] autorelease]; 
    // do stuff... 
    return mutableArray; 
} 

就個人而言,我經常當我從這樣的方法返回時,將一個可變數組變成一個NSArray只是因爲我覺得它以某種方式「更安全」或更「正確」。儘管說實話,我從來沒有遇到過將一個可變數組轉換爲NSArray的問題,所以這可能是一個非現實問題 - 但是對於這種情況,是否有最佳做法?

回答

9

我用來做return [NSArray arrayWithArray:someMutableArray],但我慢慢相信,它不提供任何實際的好處。如果您的API的調用者將返回的對象視爲已聲明類的子類,那麼他們做錯了。

[注意:請參閱下面的bbum警告。]

+1

我普遍同意。但是,如果調用代碼與返回值混淆的可能性會導致嚴重問題,那麼防禦性複製是一個好主意。對於框架代碼尤其如此。 –

+0

如果調用代碼正在改變你的API所說的應該被視爲不可變的東西,他們應該做一個'-mutableCopy'。否則,做錯了。 ;)(沒有什麼是被防守阻止你,如果你覺得你必須,雖然) – Wevah

+4

真正的問題,雖然是如果你返回一個可變數組引用數組以後可能發生突變,主叫方接收一個NSArray *可能假設內容永遠不會改變......並且......好吧...... * BOOM *。 – bbum

5

這是很常見返回一個NSMutableArray投作爲一個NSArray。我認爲大多數程序員會意識到,如果他們貶低一個不可變的對象並進行變異,那麼他們會引入討厭的錯誤。另外,如果您有NSMutableArray ivar someMutableArray,並且您在KVC訪問器方法中返回[NSArray arrayWithArray:someMutableArray],則它可能會混淆KVO。你會開始得到「對象被釋放與觀察員仍然附加」的錯誤。

0

的NSArray事實上是一個類簇,而不是一種類型的,無論如何。所以在你看到NSArray的任何地方,無論如何它已經是幾種不同類型之一。因此,「轉換爲NSArray」有點誤導;一個NSMutableArray已經符合NSArray接口,這是大多數處理的內容。

CocoaObjects fundamentals

在任何情況下,因爲你是返回一個數組(而不是保持它之後,由於自動釋放),你可能並不需要擔心的數組是否爲可變的。

但是,如果你保持陣列,那麼你可能要做到這一點,以防止客戶端更改內容。

+1

沒有NSArray協議。 NSMutableArray是NSArray類的一個子類。 –

+0

彼得, 你是絕對正確的,這是我的一部分在一個錯誤 - 意味着「接口」在那裏。我相應地更新了我的答案。 – AlBlue