2014-02-11 118 views
10

當從使用NSMutableArray動態構建數組的方法返回NSArray(或NSDictionary等)時,執行此操作並避免隨機數的標準方法是什麼使用ARC時內存泄漏?從具有NSArray返回值的方法返回NSMutableArray對象

例如,假設我們有一些類名稱的列表,我們想手動過濾並抓住所有以給定的字母開始的名字:

- (NSArray *)getNamesByFirstLetter:(NSString *)firstLetter 
{ 
    NSMutableArray *returnValue = [[NSMutableArray alloc] init]; 
    for(id item in self.names) 
    { 
     if([item hasPrefix:firstLetter]) 
     { 
      [returnValue addObject:item]; 
     } 
    }   
    return returnValue; // just return the above array 
} 

當談到回國價值,我能想到的四種可能的方式來做到這一點:

  1. 返回的NSMutableArray直接(如上)

    return returnValue; 
    
  2. 返回使用NSArray arrayWithArray一個copy

    return [returnValue copy]; 
    
  3. 回程:

    return [NSArray arrayWithArray:returnValue]; 
    
  4. 創建NSArray,手動設置NSMutableArraynil

    NSArray *temp = [NSArray arrayWithArray:returnValue]; // could use [returnValue copy] here too 
    returnValue = nil; 
    return temp; 
    

當一個程序使用ARC時,這四種方法之間是否存在真正的區別,還是僅僅歸結爲個人偏好?

另外,除了可能的內存泄漏之外,當使用一種方法而不是另一種方法時,還會有其他的含義嗎?

請注意,如果這是重複的,請告訴我,我將回答這個問題。我試圖搜索,但很難將問題簡化爲幾個搜索條件。

+3

沒有詳細說明,這些都不會導致啓用ARC的內存泄漏。我必須指出,雖然4和3在ARC環境中是等效的 – Jack

回答

9

在啓用ARC的情況下,您的所有四個選項都可以正常工作(即,您提出的任何解決方案都不會導致內存泄漏)。

但是,您提出的4種解決方案做的事情稍有不同。號碼1將返回一個NSMutableArray,這可能不會導致問題,因爲NSMutableArray將對NSArray所有相同的消息做出響應(但返回的對象將是可變的,您可能不需要)。

選項2和選項3 & 4(在ARC下相同)之間存在細微差異。如果returnValuenil,則選項2將返回nil,但選項3 & 4將返回空的NSArray。 (無論哪種行爲都可能是可取的;您應該決定如何讓這種方法行爲起來)。另外,-copy可能比+arrayWithArray更快。

我會去與選項2

+0

有道理。我只是習慣於用垃圾收集環境工作,我想我只是有點偏執。此外,進一步的研究導致我[這個問題](http://stackoverflow.com/questions/14849570)和[這個問題](http://stackoverflow.com/questions/1391914),它說'arrayWithArray'是顯式設置爲autorelease,而'copy'不一定。假設這種差異只對不使用ARC的程序很重要嗎? – valverij

+0

@valverij在垃圾收集環境中,將變量設置爲null也不是必需的(或者甚至是不可取的)。此外,ARC隱藏了程序員自動釋放和簡單釋放之間的區別,所以在編譯ARC時忽略這種特殊差異是安全的。 – dasblinkenlight

+0

@dasblinkenlight,我知道垃圾回收環境並不要求你明確地將變量設置爲'null',這就是爲什麼我擔心Objective-C錯過了一些東西。不過,感謝ARC知道所有這一切,這很好。 – valverij

3

第一件事:第一件事:你討論的方法都不會導致ARC下的內存泄漏。此外,第四種方法並不要求您將returnValue設置爲nil - 編譯器足夠聰明,可以獨立處理returnValue。這使得第四種方法與第三種方法完全相同。

此外,在returnValue上調用copy與從其內容創建新數組相同,因此第二種方法與後兩種方法相同。

這給我們留下了兩種方法 - 第一種和第二種/第三種/第四種。它們之間的主要區別在於用戶能夠對數組從他們的方法中獲得迴應。第一種方法讓用戶修改數組;最後三個沒有。決定你更喜歡哪種行爲取決於你。

+1

錯誤,但數字2會給出'NSArray',而不是'NSMutableArray',因爲調用了copy,而不是mutableCopy。 – Gavin

+0

所以基本上2,3和4都是基本相同的。 – Gavin

+0

@Gavin這是固定的,謝謝! – dasblinkenlight

0

一兩件事,旁邊還有在給定的例子無泄漏,是人人都知道的NSArray 可能可變的。如果您通過方法調用獲取它,則無論您是複製它還是按原樣使用,隨時準備進行更改,都取決於您。這就是爲什麼不可變屬性經常被聲明爲複製而不是強壯的原因。爲該屬性指定可變值將做真正的複製,並且指定不可變的值很便宜。

tl; dr:剛剛返回returnValue,沒關係。