内存泄漏问题

时间:2011-02-08 09:14:11

标签: iphone

我使用以下函数将图像加载到UITableViewCell。但是当我使用Debugger运行我的应用程序时,每当我滚动[pool release]时,它就会在UITableView处崩溃。我该怎么做才能解决这个问题?提前致谢。

- (void) loadImage{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    imageURL = [imageURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];      
    //NSLog(@"img url cell**** %@",imageURL);  
    self.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
    //self.image = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];

    [pool release];
}

3 个答案:

答案 0 :(得分:5)

由于您使用的是NSAutoreleasePool,我猜这个加载映像正在一个不是主线程的线程中运行。它是否正确?如果是这种情况,你在这个非主线程中进行UIKit调用(self.image = ...),这可能是你遇到的崩溃的可能来源。所有UIKit更新必须在主线程中进行,因为UIKit不是线程安全的。尝试更换:

self.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];

通过

[self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]] waitUntilDone:YES];

注意我猜测setter的名称是 setImage :,如果setter选择器的名称不同,则可能需要更正。

答案 1 :(得分:0)

首先,建议使用[pool drain]而不是[pool release]。 但是我在这里看到另一个潜在的问题:根据你的代码,你最初在你新创建的自动释放池之外定义了imageURL(我没有看到imageURL的任何alloc / init,它来自哪里?它是一个表格单元实例吗?)然后你用一个新分配的和自动释放的字符串重新分配imageURL:[imageURL stringByAddingPercentEscapesUsingEncoding:...]。最后,当您释放池时,新的imageURL将被释放,因此最后您所拥有的是先前分配的imageURL的泄漏。我可以期待在这一点上,当从内部自动释放池退出时,运行循环自动释放尝试再次释放imageURL(例如,但我需要看到您的代码完全理解)已被解除分配。

您可以尝试将stringByAddingPercentEscapesUsingEncoding:的结果分配给其他名称(例如myImageURL)吗?

答案 2 :(得分:0)

这里有点不对劲。

首先,您对自动释放池的需求非常清楚地表明您没有在主线程上执行此操作。 UIKit不是线程安全的。任何UI工作都需要在主线程上完成,否则会发生未定义的行为,例如崩溃。

其次,您正在使用看起来像图像的同步URL下载。如果您从磁盘上的文件URL加载它,请更正我。同步图像下载可能是您将其移动到单独的线程中的原因,因为它阻止了您的UI吗?关于网络访问,你应该学习的第一件事就是永远不要在主线程上使用同步API。您是否考虑过查看NSURLConnection类以进行异步下载?

第三,这需要重新设计,以便图像下载不直接链接到单元格的显示。

显示表格单元格应该在主线程上与UI的其余部分一起完成。显示单元格时,应调用异步下载图像。应缓存图像下载,并在图像下载完成时通过委托回调通知单元格。然后它应该显示图像。

您可以在NSOperation s中包装这些内容并使用NSOperationQueue来管理它们。请查看这些类的文档,并查看示例代码,以了解如何使用它们。