2011-09-23 50 views
1

這是針對使用Xcode 4在Objective-C中編寫的iPhone應用程序。您是否釋放函數中返回的對象?

快速的問題是,如果您有一個函數返回一個在該函數中被ALLOC化的NSArray,您是否必須釋放它?

下面是更詳細的問題。

我跑在我的iPhone應用程序「分析」,它會抱怨我的函數

該函數創建一個NSArray中出的NSMutableArray,並返回NSArray的一個可能的內存泄漏。我正在做的是獲取一個類對象的NSMutableArray,並從它們中創建一個NSStrings的NSArray。我已儘可能簡化代碼以顯示問題,因此如果看起來沒有做任何有用的事情,請不要擔心。

-(NSArray *)encodeArray 
{ 
    // I use a NSMutableArray here because I do not know how big the starting 
    // array will be (I hard coded the 20 here for now) 
    NSMutableArray *tmp = [[NSMutableArray alloc]init ]; 

    for (int y = 0;y<20;y++) { 
     // create the NSString object and add it to the tmp array 
     NSString *cardcount = [NSString stringWithFormat:@"%i%",y]; 
     [tmp addObject:cardcount]; 
    } 
    // create the array we will be returning out of the NSMutableArray 
    NSArray *array = [[NSArray alloc] initWithArray:tmp copyItems:YES]; 
    // release the tmp array we created. 
    [tmp release]; 

    // return our array 
    // This is the location of the potential memory leak. SHOULD I RELEASE THIS 
    // If I DO - HOW DO I RETURN IT. 
    return array; 
} 

我需要釋放數組嗎?如果是這樣,我還能如何退還?也許有更好的方式來執行我正在做的事情?

總體目標是創建一個NSArray,以便我可以使用NSUserDefaults來保存應用程序狀態。

回答

1

作爲一個經驗法則;如果你(通過我的意思是對象的當前範圍)保留/複製/等一個對象,那麼你必須釋放/ autorelease它的地方。因爲撥打encodeArray的人不會保留array,他們不負責釋放它。因此,需要將其設置在返回之前被自動釋放:

-(NSArray *)encodeArray 
{ 
    // I use a NSMutableArray here because I do not know how big the starting 
    // array will be (I hard coded the 20 here for now) 
    NSMutableArray *tmp = [[NSMutableArray alloc] init]; 

    for (int y = 0;y<20;y++) { 
     // create the NSString object and add it to the tmp array 
     NSString *cardcount = [NSString stringWithFormat:@"%i%",y]; 
     [tmp addObject:cardcount]; 
    } 

    // create the array we will be returning out of the NSMutableArray 
    // Named initializers indicate that the object will be autoreleased: 
    NSArray *array = [NSArray arrayWithArray:tmp]; 

    // release the tmp array we created. 
    [tmp release]; 

    // return our array 
    return array; 
} 

或者:

-(NSArray *)encodeArray 
{ 
    // I use a NSMutableArray here because I do not know how big the starting 
    // array will be (I hard coded the 20 here for now) 
    NSMutableArray *tmp = [[NSMutableArray alloc] init]; 

    for (int y = 0;y<20;y++) { 
     // create the NSString object and add it to the tmp array 
     NSString *cardcount = [NSString stringWithFormat:@"%i%",y]; 
     [tmp addObject:cardcount]; 
    } 
    // create the array we will be returning out of the NSMutableArray 
    NSArray *array = [[NSArray alloc] initWithArray:tmp]; 

    // release the tmp array we created. 
    [tmp release]; 

    // return our array 
    return [array autorelease]; 
} 
+0

三江源的解釋和示例代碼備份。它不僅解決了我的問題,而且還學到了一些東西。 – Johnne

3

通常,您希望在此情況下返回一個自動釋放的數組。如果你在你的函數中釋放它,它將在你的調用者有機會保留它自己的副本之前被釋放。如果你不自動釋放它,那麼當你的調用者保留返回的對象時,你將有一個2的保留計數,並且可能會泄漏。

所以,只要改變你的return語句是:

return [array autorelease];