2010-01-24 26 views
1

當試圖重用現有NSMutableArray(爲了節省內存)時,我得到了一些泄漏(由儀器觀察)。重用NSMutableArray

基本上我創建了一個NSMutableArray,用對象(UIImages)填充它並將其傳遞到保留它的另一個對象上。不過,我現在需要再次使用NSMutableArray。我想我會釋放其所有對象,空它,一切都將被罰款,但儀器將報告的CALayer泄露對象(??)從那時候方法,它看起來如下:

NSString *fileName; 
NSMutableArray *arrayOfImages = [[NSMutableArray alloc] init]; 

// fill the array with images 
for(int i = 0; i <= 7; i++) { 
    fileName = [NSString stringWithFormat:@"myImage_%d.png", i]; 
    [arrayOfImages addObject:[UIImage imageNamed:fileName]]; 
} 

// create a button with the array 
aButton = [[CustomButtonClass buttonWithType:UIButtonTypeCustom] 
        initWithFrame:someFrame 
        imageArray:arrayOfImages]; 

// release its objects 
for(int i = 0; i < [arrayOfImages count]; i++) { 
    [[arrayOfImages objectAtIndex:i] release]; 
} 
// empty array 
[arrayOfImages removeAllObjects]; 

// fill it with other images 
for(int i = 0; i <= 7; i++) { 
    fileName = [NSString stringWithFormat:@"myOtherImage_%d.png", i]; 
    [arrayOfImages addObject:[UIImage imageNamed:fileName]]; 
} 
// create another button with other images (same array) 
aSecondButton = [[CustomButtonClass buttonWithType:UIButtonTypeCustom] 
        initWithFrame:someFrame 
        imageArray:arrayOfImages]; 

[arrayOfImages release]; 

爲求清晰,我的按鈕init方法如下所示:

- (id)initWithFrame:(CGRect)frame 
     images:(NSArray *)imageArray 
{ 
    if(self = [super initWithFrame:frame]) { 
     myImageArray = [[NSArray arrayWithArray:imageArray] retain]; 
    } 
return self; 
} 

我知道我可以只創建一個新的NSMutableArray和這個問題是在,但它讓我很煩,不能夠只是重複使用舊陣列。可能是什麼問題呢?

回答

6

當試圖重用現有 的NSMutableArray(以 保存記憶),我得到了一些泄漏(由 儀器obvserved)。

一個數組需要非常少量的內存;每個指針存儲4個字節(在32位系統上)+一小部分開銷。除了最特別的情況外,重新使用數組試圖節省內存是浪費時間。

// release its objects 
for(int i = 0; i < [arrayOfImages count]; i++) { 
    [[arrayOfImages objectAtIndex:i] release]; 
} 
// empty array 
[arrayOfImages removeAllObjects]; 

您沒有保留對象,因此您不應該釋放它們!上述內容表明您的應用沒有崩潰表明您可能在其他地方過度保留對象。

我知道我可以只創建一個新的 的NSMutableArray以及與此 問題結束,但它讓我很煩,不能夠 只重用舊的陣列。什麼 可能是問題?

該代碼中沒有任何東西會作爲內存泄漏出現。恰好相反;你是過度釋放物體。

而上述表明你真的需要重新訪問memory management guidelines作爲重新使用數組而不是釋放數組並創建一個新的數組,真的沒有任何與這個問題有關。

+0

+1,特別是關於數組大小的信息。 – 2010-01-25 04:03:28

+0

非常感謝這個非常具有描述性的答案! – hwaxxer 2010-01-25 09:46:52

4

你不需要這個部分:

// release its objects 
for(int i = 0; i < [arrayOfImages count]; i++) { 
    [[arrayOfImages objectAtIndex:i] release]; 
} 

這是對所有權的規則。您沒有保留圖像

[arrayOfImages addObject:[UIImage imageNamed:fileName]]; 

因此它不是您的責任釋放它們。它是NSMutableArray,當-addObject被調用時,它會保留它們,所以它的NSMutableArray有責任在調用-removeObject或其他類似的名稱時釋放它們。你發現的泄漏可能是因爲系統因這種過度釋放而感到困惑...我也建議在XCode中執行「構建和分析」。

0

泄漏儀器會告訴您泄漏的物體在哪裏首先分配爲。其中一個圖像泄漏意味着您在其他地方使用了該圖像,並且沒有在那裏釋放 - 泄漏無法告訴您在哪裏,因爲它無法向您顯示不存在的代碼。

事實上,正如其他人指出的,這有點令人驚訝,因爲代碼原本是過度釋放對象,應該已經崩潰。但它沒有崩潰的事實是一個很好的跡象,你正在使用陣列中的圖像並過度保留它們。