UIImageView / UIImage“Memory Tag 70”在滚动时释放时间

时间:2012-01-06 06:14:43

标签: iphone ipad memory uiscrollview uiimage

我有一个很长的水平分页滚动视图,对于每个页面,我都放了一个全屏UIImage。

由于价格昂贵且无需一次添加所有UIImage,目前我懒得加载图片(pageIndex-1 + pageIndex + pageIndex + 1的图片,使用NSOperationQueue FYI),并删除所有其他UIImageViews。

Instrument报告的内存使用量在正常使用情况下是可以接受的,但我发现如果我继续滚动(连续切换30页),脏内存会不断增加,尤其是“Memory Tag 70”,我相信它是原始的来自UIImage的数据。一旦我停止触摸应用程序3~4秒,所有“Memory Tag 70”将自动释放。

我已经将NSLog放在了几个地方,我确信UIImageViews在超出“显示范围”时会从超级视图中删除。

滚动是否阻止主循环释放这些内存?我该怎么做才能防止这种情况发生?谢谢!enter image description here

p.s Dirty Size的大幅下降是我停止滚动的时刻。

3 个答案:

答案 0 :(得分:2)

我会尝试以下方法:

  1. 不要使用[UIImage imageNamed:]来加载图像。这在内存标签70中构建。
  2. 使用实例方法initWithContentsOfFile:并显式自动释放它。注意:这样做意味着失去缓存优势[UIImage imageNamed:]给出。但试一试。
  3. 在图像分配发生的代码周围使用@autoreleasepool(而不是NSAutoreleasePool)。无论ARC如何,都可以使用它。

答案 1 :(得分:2)

(只是一个猜测,我远离Xcode来测试它,并假设一个非ARC环境)

您可以使用

代替[otherImageView removeFromSuperview]
UIImage *image = [otherImageView.image retain];
otherImageView.image = nil;
[image release]; // the image won't go to the main autorelease pool
[otherImageView removeFromSuperview]; // No one has references to otherImageView, so it goes to the autorelease pool

避免图像进入自动释放池。

答案 2 :(得分:0)

从图表中可以看出内存消耗水平关闭,这与缓存的图像一致,然后在滚动停止时释放(可能在滚动视图中通过内部自动释放)。缓存和内存增加可能使您的滚动更顺畅。如果你真的需要防止内存建立,那么你需要自己手动分配和释放图像(回应AnlmlsH建议放弃imageNamed)。

但是消除缓存可能会导致急剧滚动....经典的时间/空间权衡,你需要确定哪一个更适合你应用的情况。