iphone UIImage内存泄漏

时间:2010-12-03 18:31:25

标签: iphone uiimage nsdata

我正在使用UIScrollView实现图像浏览器。由于内存成本问题,我要实现图像动态加载(我不想使用CATiled Layers,因为它会强制用户等待加载每个tile)。

我尝试过一种方式:

- (UIImageView*) ldPageView{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool
NSError *error;
NSData *imData = [NSData dataWithContentsOfURL:ldPageRef options:NSDataReadingUncached error:&error];
UIImage *im = [[UIImage alloc] initWithData:imData];
ldView = [[UIImageView alloc] initWithImage:im] ;
[ldView setFrame:pageRect];
[pool release];  // Release the objects in the pool.
return ldView;
}

即便如此,

- (UIImageView*) ldPageView{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool
CGDataProviderRef provider = CGDataProviderCreateWithURL ((CFURLRef)ldPageRef);
CGImageRef d = CGImageCreateWithJPEGDataProvider(provider,nil, true,kCGRenderingIntentDefault);
UIImage *im = [[UIImage alloc] initWithCGImage:d];
ldView = [[[UIImageView alloc] initWithImage:im] autorelease];
[im release];
CGDataProviderRelease(provider);
CGImageRelease(d);
[ldView setFrame:pageRect];
[pool release];  // Release the objects in the pool.
return ldView;
}

但是每当我在模拟器和iPad上都尝试它时,内存就会爆炸。我用仪器运行了我的代码,没有报告泄漏。 ldView是一个istance变量,它在对象dealloc上被释放为ldPageRef(肯定会被调用)。

我也尝试将NSURLCache sharedCache设置为nil或为零,但它仍然在发生。

我已经阅读了内存管理指南,但是每个方面对我来说都没问题。 请帮忙

4 个答案:

答案 0 :(得分:2)

很可能是你创建UIImage的方式。尝试创建图像..

[UIImage imageWithData:imData];

而不是

[[UIImage alloc] initWithData:imData];  

这将返回一个自动释放的对象(它是一个类方法),这样您以后就不必尝试自己释放它。

答案 1 :(得分:2)

尝试使用

UIImage *im = [UIImage imageWithData:imData];

而不是

UIImage *im = [[UIImage alloc] initWithData:imData];

如果可能,请始终避免使用alloc,否则必须确保手动释放对象。

答案 2 :(得分:1)

您永远不会释放您的alloc'd对象。你需要改变:

[[UIImage alloc] initWithData:imData];
[[[UIImageView alloc] initWithImage:im];

为:

[[[UIImage alloc] initWithData:imData] autorelease];
[[[UIImageView alloc] initWithImage:im] autorelease] ;

答案 3 :(得分:0)

确实我在UIImageView中发现了内存泄漏。你永远不会关注它,因为你可以一直打开App包中的图像,这些图像都是由iOS缓存的。

但是如果您从网络下载了大量图像(例如40张iPhone相机照片),请将它们保存到文档中并在子视图控制器中反复打开它们,应用内存泄漏。您不需要有40个不同的图像,一次又一次地加载一个图像就足够了。

您的测试应用程序已禁用ARC,并且每次按下控制器时,都会从文件加载图像并显示在子视图控制器中。

在子视图控制器中,您将创建一个UIImageView并将UIImage对象分配给图像视图的.image属性。离开子视图控制器时,可以正确释放图像视图。在iPhone 4s上,您的应用程序将无法打开超过80张图像。我的大约70张图像(使用iOS 6.1)崩溃了。在崩溃之前看看intruments app。内存中充满了CFMalloc块。

我发现的解决方案很简单:在释放图像视图之前将image属性设置为nil。再次,看看仪器应用程序。它现在看起来像你期望的那样,你的应用程序不再崩溃。

我认为同样的泄漏适用于UIWebView用于显示图像的任何内容,Apple也不知道它。