记忆泄漏 - 目标c

时间:2011-08-14 16:32:07

标签: objective-c memory-management

  

可能重复:
  Objective C Memory Management

我的代码在这里显示内存泄漏:

NSMutableArray* newImageArray = [[NSMutableArray alloc] init];
NSMutableArray* newMediaArray = [[NSMutableArray alloc] init];

if (self.categoryIndex == 0) {
    for (int i=1; i < [categoryArray count]; i++)
    {
        newImageArray = [NSMutableArray arrayWithArray:[newImageArray arrayByAddingObjectsFromArray:[self getImageArrayByCategoryIndex:i]]];
    }
}
else {
    newImageArray = [self getImageArrayByCategoryIndex:self.categoryIndex];
}

for (int i=0; i < [newImageArray count]; i++)
{
    Media* media = [[Media alloc] init];
    NSString* imageFile = [newImageArray objectAtIndex: i];

    media.imageFile = [UIImage imageNamed:imageFile];
    media.imageLabel = [[imageFile lastPathComponent] stringByDeletingPathExtension];
    media.soundFile = [appFolderPath stringByAppendingString:[[[imageFile stringByDeletingPathExtension] stringByAppendingString: @".wav"] stringByReplacingOccurrencesOfString: IMAGES_FOLDER withString: SOUNDS_FOLDER]];

    [newMediaArray addObject:media];
}

self.mediaArray = newMediaArray;

[self setNextMediaIndex];

我没有发布媒体,因为它正被newMediaArray使用(由mediaArray使用,用于我的主要对象)。当我释放主要对象时,不应该释放一切吗?

4 个答案:

答案 0 :(得分:1)

看起来你以各种方式泄漏到处都是

newImageArray已分配但从未发布,此外,您将覆盖您在第一行代码中使用其他版本分配的版本。因此,即使您在此代码段结束时发布它,也会释放错误的版本。看起来你甚至不需要分配这个。

newMediaArray已分配但从未发布,如果您使用mediaArray创建该属性的代码,则将其分配给属性@synthesize,具体取决于您声明该属性的方式, setter将retainnewMediaArray创建泄漏。

media被分配但从未被释放,它被添加到NSMutableArray,这意味着它将被数组保留。如果您在for循环中释放media时应用崩溃,则问题出在其他地方

Memory Management Programming Guide几乎是必读的

答案 1 :(得分:0)

当诸如newMediaArray之类的NSMutableArray添加对象时,它将保留该对象。您不需要(也不应该)代表数组保留对象。这基本上是Objective-C中的内存管理工作方式:每个对象都保留它引用的内容,并在完成后释放它们。 newMediaArray是它自己的对象,因此它将管理自己的引用。

您应该在media循环体的末尾附近释放for,因为您已经完成了使用该对象。如果你没有发布它,那么你将失去对它的引用,你将来也无法发布它。

答案 2 :(得分:0)

你做

[newMediaArray addObject:media];

这意味着newMediaArrayretain上完成了media。然后,您可以发布media(您应该)。只要数组引用它,数组方法中的retain将保持活动状态。如果你没有在你的方法中释放它,保留计数将保持为2,即使数组释放它,它仍然是1并且不被解除分类。

你可以这样做:

Media *media = [[[Media alloc] init] autorelease];

然后自动释放池会及时释放它,但不会在此方法结束之前释放它。

答案 3 :(得分:0)

你需要在循环的底部有[media release]语句。在将newMediaArray属性分配给mediArray之后,也应该释放{{1}}。