2011-07-30 62 views
4

如果我使用的方法返回一個NSArray,並且該方法我建立的結果作爲一個NSMutableArray的裏面,我經常很想把return [NSArray arrayWithArray:myMutable],而不是return myMutable只是把它鎖起來,防止突變通過一些不正當的其他可能檢查其上的isMemberOfClass並執行一些突變的代碼。在返回它們之前將mutables轉換爲immutables是否很重要/很好?

如果我只是編碼自己,我知道我會把返回值作爲他們說,他們是,沒有任何理由返回之前將其切換到的NSArray?我在這裏沒有看到的任何優勢?

+1

「當你調用一個方法並接收返回一個對象,該對象可以是即使該方法的返回類型特徵它作爲不可變可變的。沒有什麼可以阻止聲明的方法返回一個不可變對象,但返回一個類儘管你可以用introspection來確定接收的對象是否實際上是可變的或不可變的,但你不應該總是使用對象的返回類型來判斷它的可變性。來自[Object Mutability](http://bit.ly/mXOexA) – albertamg

+1

謝謝,這是一個很好的參考。 –

回答

4

這樣做並沒有真正的優勢;一般而言,您應該期望您的界面的客戶將尊重該界面的合同。

在許多基礎值和容器類型(NSString等),它的問題甚至更少的情況下;由於免費橋接機制的實現細節,可變和不可變變體實際上都是同一類的實例。例如,NSString和NSMutableString的init方法實際上都返回__NSCFString的實例,該實例從兩者繼承。該對象保留了您調用的API的可變性或不變性,但您無法通過查看該類是否可變來判斷。

換句話說,無論您是否創建了可變對象,[aString isKindOfClass:[NSMutableString class]]將始終返回YES。因此,使用該API來檢查是否可變是不可行的,所以不用擔心API的客戶端是否會嘗試這樣做。

編輯: 我最初說,你無法通過檢查類的數組無論是可變的或不說,但事實證明,在NSArray的情況下,你可以告訴。 (感謝@albertamg捕捉錯誤。)我已經改變上面的例子使用NSString,這是一個情況下,你真的不能出來。但是,一般來說,如果有人將你返回的對象當作不可變形的對象處理時,我會認爲它是一個錯誤,並且不會擔心它周圍的編程。再次

編輯: 因此,原來在OS X和iOS的某些版本中,你無法察覺的NSArray mutablility下去,但在最近的版本,他們已經改變了,這樣你可以執行。但是,您仍然無法在NSString中檢測到它。因此,從所有這一方面帶回家的教訓是,您不應該在作爲class cluster的一部分的對象上使用isKindOfClass:

+0

'isMemberOfClass' retuns'NO'因爲'NSArray'是一類集羣,當你創建一個是子類的實例,你會得到什麼。 'isKindOfClass'會產生預期的結果(包括測試可變性)。 – albertamg

+0

我確實需要'isMemberOfClass',你說得對。但關於可變性的觀點在這裏。它會以任何方式返回YES。 –

+0

你是對的;我只是嘗試一下。但是我說的NSString是真的;我會改變我的例子來使用NSString。感謝您捕捉錯誤。 –

2

我已經寫了NSArray的一個類別,它包含純功能性的方法和基於返回原陣列上不可變對象是必須的。但我不會在其他任何環境中打擾。也許作爲公共消費框架中的防白癡措施。

如果你想在突變的代碼路徑不可改變的地方你可能不應該由「放下障礙」予以糾正的問題可以這麼說。

1

不是真的,如果你正在寫一個庫,你要保護從開始改變的原因這是一個好主意的陣列,這取決於如何的代碼是兩個部分連接緊密,返回的NSArray而不是NSMutableArray的是捕捉可能的錯誤一個很好的做法,但事業創建新陣列需要CPU週期,你必須基本上使稱自己根據情況,我往往喜歡把它安在像這樣的情況,我會經常在我的代碼中添加NSParameterAsserts只是爲了儘可能快地捕捉可能的邏輯問題,使用objective-c作爲一種動態語言,似乎是一個很好的做法,要小心這種事情。我猜如果它不在代碼中,那麼在一段時間內調用重要的部分,我會像你那樣做。

相關問題