苦苦挣扎着内存管理并创建数组方法

时间:2011-07-04 11:48:39

标签: iphone ios4 memory-management memory-leaks methods

我在调用方法后努力找到释放数组的正确方法。我想知道是否有更好的方法来实现我尝试用我的方法实现的目标:

- (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];
...

我的应用程序在这里泄漏了内存,而且我一直在寻找一种方法来释放所有内容。

3 个答案:

答案 0 :(得分:2)

您的方法应返回一个自动释放的数组,然后由调用它的方法保留,如果它想要/需要保留它。

- (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

答案 1 :(得分: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

所有其他方法都应返回自动释放的对象。

答案 2 :(得分: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答案。两者都是可能的方式。