在不同的缩放比例下使用CGContextDrawTiledImage会导致大量内存增长

时间:2010-10-16 23:42:20

标签: iphone cocoa-touch core-graphics

我在app上工作,在可缩放的UIScrollView中有一个视图。当用户放大或缩小时,我会重绘UIScrollView中的视图,使其更加美观和清晰。该视图有一个我用CGContextDrawTiledImage绘制的背景图片。

我注意到每次切换到新的缩放级别时内存使用量都会增加。看起来CGContextDrawTiledImage会将图像缩放到不同大小的某个位置。所以,如果我从1.0到1.1倍变焦,内存使用会增长。回到1.0不会导致它增长,但是然后到1.05然后1.2会导致它增长两倍。回到1.1而没有增长。当然,缩放级别在用户控制之下,因此我无法控制发生了多少缩放级别。现在我的背景图像有点大(512x512),所以这会导致内存使用量快速增长非常。它不会在Instruments中显示为内存泄漏,只是额外的分配永远不会被释放。

我试图找到一种方法来释放看似正在创建的缓存,但没有运气。例如,它似乎没有响应低内存警告。

我还尝试将视图的backgroundColor设置为使用colorWithPatternImage创建的UIColor,但这不起作用,因为我通过更改图形上下文的CTM来进行缩放,而不是通过设置视图的变换。

关于如何防止内存使用爆炸的任何想法?

4 个答案:

答案 0 :(得分:0)

您是否尝试将传递的矩形更改为CGContextDrawTiledImage而不是(或更早)更改上下文的CTM?

答案 1 :(得分:0)

你是如何加载图像的?如果您正在使用+ imageNamed:那么加载的图像将被iOS永久缓存,+ imageWithContentsOfFile:更好。

答案 2 :(得分:0)

每次我在图形上下文的CTM中使用不同的缩放比例时,Quartz显然会使用CGImage保留某种缓存。为了解决这个问题,当我收到低内存警告时,我会释放图像,然后在我需要它时懒洋洋地重新初始化它。不完美,但我能找到最好的。

我向Apple提交了一个错误,但没有真正的回复。

答案 3 :(得分:0)

在Jacques回答的基础上,我发现只需复制CGImageRef并释放旧版本即可清除缓存。其他比例的缓存不会复制到新的引用。

我从任何改变比例的地方都这样说:

 /**
 * Switcheroo to persuade CGImage to drop the many megabytes of cache 
 * it creates when changing scale.
 */
- (void)discardRenderedImageCaches {
    CGImageRef newImageRef = CGImageCreateCopy(renderedImageRef);
    CGImageRef oldImageRef = renderedImageRef;
    renderedImageRef = newImageRef;
    CGImageRelease(oldImageRef);
}