2012-08-27 60 views
2

在下面的代碼中,如果我返回NSMutableArray而不是NSArray,它是方法的返回類型,我不會收到任何警告或編譯錯誤。
如果方法的返回類型是NSArray,將返回值類型從NSMutableArray轉換爲NSArray是否好習慣?

但是,通過使用-copy方法將返回值轉換爲NSArray是否是一種很好的做法,如下面的代碼所示?
或者我應該返回NSMutableArray?

+(NSArray *)returnImutableArray { 
    NSMutableArray *arr = [[NSMutableArray alloc] init]; 
    [arr addObject:@"a"]; 
    [arr addObject:@"b"]; 

    //return arr; // no warning 
    return [arr copy]; 
} 
+0

如果您不使用ARC,您的代碼有可能泄漏 – tikhop

回答

6

我認爲這基本上是個人偏好。在返回數組之前複製數組會導致(可能很小的)性能損失。好處是你可以完全防止結果突變。但是,我通常不會遇到麻煩。由於該方法的聲明返回類型是一個不可變的 NSArray,如果您嘗試調用NSMutableArray的突變方法之一,編譯器會警告您,除非您避免這種方式(通過強制轉換爲NSMutableArray)。

因此,簡而言之,這是個人偏好,我個人通常不打擾不可變的副本。

+0

感謝您的明確解釋。 –

0

這一切都取決於你想用數組來實現什麼。

如果你真的不想或不需要修改返回的數組,請將它作爲NSArray返回。 你可以將它作爲數組返回,而不需要複製它。

在這兩種情況下,都不要忘記內存管理。

您不應該返回保留計數> 0的任何東西。

+(NSArray *)returnImutableArray { 
    NSMutableArray *arr = [[NSMutableArray alloc] init]; 
    [arr addObject:@"a"]; 
    [arr addObject:@"b"]; 

    NSArray * returnArray = [NSArray arrayWithArray:arr]; 
    [arr release]; 
    //return arr; // no warning 
    return returnArray; 
} 

或者你可以這樣做:

+(NSArray *)returnImutableArray { 
    NSMutableArray *arr = [[NSMutableArray alloc] init]; 
    [arr addObject:@"a"]; 
    [arr addObject:@"b"]; 
    //return arr; // no warning 
    return [arr autorelease]; 
} 

沒有必要複製NSMutableArray中,延續NSArray的,所以如果你這樣做你的代碼永遠不會打破。

+0

我假定他的代碼是用ARC編譯的。 –

+0

@AndrewMadsen你是對的。我使用ARC。我不擅長非ARC。 –

+0

恕我直言,任何使用iOS SDK的應用程序在使用ARC編譯之前都應該感到舒服...... – flovilmart

0

默認情況下,我返回內部可變實例的不可變copy。不僅僅是NSArray,還有其他幾種類型。

我不想讓可變對象四處移動,儘管只要您將其視爲具體內容,它不會變化。

我認爲這是一個更好的默認,因爲它如果共享最小化淺度複製。也就是說,如果您將結果分配給一個或多個屬性爲copy的屬性,那麼所有這些操作都必須生成具體的淺拷貝,只要它們可以有效地retain。這與您在聲明屬性時應該傾向copy這些類型的屬性的原因相同,而不是retain

在某些情況下,您只知道它的範圍是有限的,並且mutable不會退出 - 在這種情況下,我可能不打算複製副本。

+1

我不太明白這裏的推理。您正在創建一份副本,因爲調用方可能稍後必須在分配上創建副本。爲什麼不讓複製發生在分配?結果複製多次的可能性似乎非常小,而不會被複制。我同意當然在適當的屬性上使用'copy'。 –

+0

@RobNapier它消除了mutable的傳播。我試圖爲你寫一個更好的迴應,但有效地結束了迴應我的答案。也許我們寫的不同。也許我們的計劃*在統計學上有很大不同。部分原因也是爲了制定一個穩固而健全的計劃 - 以避免將確保不變性的責任推給客戶。好奇:有沒有**沒有**的情況下,你會返回一個具體的副本,而不是返回一個可變的本地? (數組,數據,字典,字符串,集合等) – justin

+1

我無法想象其中之一。我試圖想象一個錯誤,這將防止不涉及調用者瘋狂(我故意不想保護自己)。來電者不需要確保不變性。他擁有它。我返回了一個'NSArray'接口。內部結構不是他的業務。它可以通過調用者違反API(和警告抑制)而被突變,這對許多不可變對象('foo-> bar = baz',私有方法等)是真實的。我當然只是爲了本地的意思;返回伊娃是一個不同的問題(通常是一個困難的性能問題)。 –

相關問題