2012-10-27 36 views
2

首先,我没有使用ARC,因为我有更大的问题,我需要完全控制我的内存管理。加载很多远程图像 - 内存问题

以下是这种情况:我需要从服务器加载很多远程JPEG图像,并在滚动视图中显示它们。一旦用户向下滚动一下,滚动视图中的顶部图像就会释放。这是工作,包含的意见都是正常发布。 问题是,加载远程映像后,很多内存保持分配状态并且没有被释放。 这里是我的代码来获取远程图像(子类的UIImageView):

- (void)downloadImage { 
    NSData *posterData = [[NSData alloc] initWithContentsOfURL:self.url options:NSDataReadingUncached error:nil]; 
    UIImage *img = [[UIImage alloc] initWithData:posterData]; 
    [posterData release]; 
    self.image = img; 
    [img release]; 
} 
// that gets called from: 
- (void)setImageFromURL:(NSURL *)_url{ 
    [NSThread detachNewThreadSelector:@selector(downloadAndLoadImage) toTarget:self withObject:nil]; 
} 

当我检查我与仪器的代码,我的UIImageView被释放的预期,但下面还是在我的记忆stucks和修建垃圾吧: Instruments http://s16.postimage.org/rybls16ed/Screen_Shot_2012_10_27_at_8_57_52_AM.png

显然CFData,Malloc 9.00 KB,NSConcreteData都是由我的downloadImage方法产生的。 我在做什么错?这让我疯狂......你如何加载大量的远程图像内存安全? 我也尝试NSURLConnection,但它是更糟,然后更好。 :(

图像的大小变化提前6至25KB。

非常感谢!

UPDATE

我结束了使用SDWebImage它的伟大工程,是非常容易使用。

+0

你是如何声明你的“'图像'”属性?此外,您尝试下载的图像有多大? –

+0

@MichaelDautermann图像大小从6到25KB不等。 'image'属性是'UIImageView'的正常图像属性 - 在这种情况下,我将子类UIImageView。 – christopher

回答

0

是否在后台线程上下载图像?如果是,那么在哪里是NSAutoreleasePool?您必须添加:

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

// your downloading thread code here 

[pool release]; 

或为ARC:

@autoreleasepool {

// your downloading thread code here 

}

此外,如果图像下载发生在后台线程你不能做self.image = img;你应该把它在主线程,因为UI元素只能从主线程修改:

[self performSelectorOnMainThread:@selector(setImage:) withObject:img waitUntilDone:YES]; 

其实SDWebImage library为你做的一切,并有memcache和磁盘缓存

+0

我已经尝试NSAutoreleasePool,并没有改变。但感谢您在主线程中指出问题。我刚刚检出了SDWebImageLibrary,并且改进了很多。 Malloc 9.00KB几乎消失,但CFData仍然消耗大量内存。 – christopher

+0

我敢打赌,你不会放弃你的UIImageView的自定义子类的参考,并保留UIImage和NSData作为结果。但是,根据您发布的代码无法知道。 – MoDJ