2011-07-04 46 views
1

我正在努力尋找在我的方法被調用後釋放數組的正確方法。我不知道是否有更好的方法來達到我想要用我的方法來acheive:與內存管理苦苦掙扎,並創建數組方法

- (NSArray *) setupDetailArray : (NSString *) selectedCategory { 

    // Load .plist file 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"]; 

    // Load .plist into a new dictionary 
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path]; 

    // Drill down to next level 
    NSArray *faceSelection = [[NSArray alloc] initWithArray:[dict objectForKey:detailTitle]]; 
    [dict release], dict = nil; 

    // Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = [[NSMutableArray alloc] init]; 

    // Set app delegate faces to array 
    dataCenter.faces = faceSelection; 
    [dataCenter.faces release]; 

    return faceSelection; 

    // [faceSelection release], faceSelection = nil; ?????? 

} 

,我打電話給我在viewDidLoad方法

// If faceArray is empty, create it 
if (faceArray == nil) 
    faceArray = [self setupDetailArray:detailTitle]; 
... 

我的應用程序在這裏泄漏內存,和我一直在尋找一種方式來釋放一切。

回答

2

您的方法應該返回一個autoreleased數組,然後由調用它的方法保留,如果它需要/需要保留它。

- (NSArray *) setupDetailArray : (NSString *) selectedCategory { 
... 
// Create the array, but don't own it 
NSArray *faceSelection = [[[NSArray alloc] initWithArray:[dict objectForKey:detailTitle]] autorelease]; 
... 
return facesSelected; 
} 

現在調用此方法的代碼應保留對象,如果它需要它。所以,在你的viewDidLoad

if (faceArray == nil) 
    faceArray = [[self setupDetailArray:detailTitle] retain]; 
... 

如果faceArray是在你的類的實例變量,那麼你可以釋放它在你的dealloc方法。

您還泄漏內存這裏

// Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = [[NSMutableArray alloc] init]; 

    // Set app delegate faces to array 
    dataCenter.faces = faceSelection; 
    [dataCenter.faces release]; 

這應該是

// Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = faceSelection; 

我建議你閱讀(並重新讀取和重新讀取)文檔的存儲管理和閱讀關於屬性,制定者和點符號。

Apple Objective-C Memory Management

+0

好的,我會的。由於我是全新的,因此我與該文檔進行了鬥爭。我相信總有一天它會有道理! – squarefrog

+0

你只需要一遍又一遍地閱讀它,儘量找到儘可能多的例子。最終它是有道理的! –

+0

感謝您對Nick Bull的投票! – squarefrog

1
dataCenter.faces = [[NSMutableArray alloc] init]; 

您分配一個非自動釋放數組並把它分配給屬性faces(我敢打賭,它有retain修改)。

dataCenter.faces = faceSelection; 

現在你指定爲新的陣列到faces財產,但是你有沒有正確地釋放以前的NSMutableArray。

[dataCenter.faces release]; 

您現在間接釋放您的faceSelection數組。

每次運行該方法時至少泄漏一個NSMutableArray。你應該這樣做,而不是:

// Drill down to next level 
NSArray *faceSelection = [[dict objectForKey:detailTitle] copy]; 
[dict release], dict = nil; 

// Set up link to App Delegate 
UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 

// Set app delegate faces to array 
dataCenter.faces = faceSelection; 

return [faceSelection autorelease]; 

你的方法應該返回一個自動釋放對象。應該返回保留的對象的唯一方法是方法的名字:

  • 開始與alloc
  • 開始與new
  • 包含copy

其他所有方法應該返回自動釋放的對象。

+0

有趣 - 很高興知道的事情應該怎麼做 - 即所有的方法應該返回自動釋放,除了在某些情況下。我有一個問題,因爲當我重新使用此代碼時,通過回到主視圖並單擊另一行,嘗試設置dataCenter.faces = faceSelection時,我得到EXC_BAD_ACCESS; – squarefrog

1

這樣做的其他方法。

//Declare method as follows. 
- (void) setupDetailArray : (NSString *) selectedCategory arrFaceArray:(NSArray *)faceArray 
{ 
} 

,我打電話給我的方法viewDidLoad中

if (!faceArray) 
{ 
    faceArray = [[NSArray alloc] init]; //Alloc in ViewDidLoad and release in ViewDidUnload or dealloc. 
    faceArray = [self setupDetailArray:detailTitle arrFaceArray:faceArray]; 
} 

還要考慮@DarkDust答案維護自動釋放對象。這兩種方式都是可能的。

+0

我不太明白這個答案。 void方法如何返回數組對象? – squarefrog

+0

@squarefrog你在這裏傳遞引用,所以不需要返回任何數組,你會添加項目作爲參考傳遞數組。哎呀? –

+0

正確!感謝您的解釋。 – squarefrog

相關問題