我正在使用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或为零,但它仍然在发生。
我已经阅读了内存管理指南,但是每个方面对我来说都没问题。 请帮忙
答案 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也不知道它。