2010-10-16 41 views
3

我正在开发应用程序,在可缩放的UIScrollView中有一个视图。当用户放大或缩小时,我将UIScrollView中的视图重新绘制为非常锐利。该视图具有使用CGContextDrawTiledImage绘制的背景图像。在不同的缩放环境下使用CGContextDrawTiledImage导致海量内存增长

我注意到,每次切换到新的缩放级别时,内存使用量都会增加。它看起来像CGContextDrawTiledImage保持缓存在不同大小的图像的某处。所以,如果我从1.0放大到1.1倍,内存使用量会增加。回到1.0并不会导致它增长,但随后到1.05然后1.2导致它增长两倍。回到1.1并没有增长。当然,缩放级别在用户控制之下,所以我无法控制发生多少缩放级别。现在我的背景图像是一种巨大的(512x512),所以这会导致内存使用迅速增加非常。它不会在仪器中显示为内存泄漏,只是额外的分配永远不会被释放。

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

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

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

回答

0

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

我提出了一个苹果的错误,但没有真正的回应。

0

您是否试过改变您传递给CGContextDrawTiledImage的矩形而不是(或之前)更改上下文的CTM?

+0

我刚刚试了一下。它具有与上述相同的效果。太糟糕了,因为它看起来很有前途。 – Jacques 2010-10-17 01:36:22

0

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

+0

我正在使用Quartz API与CGImageCreateWithJPEGDataProvider一起加载它。我终于找到了解决方案,但没有在这里发布。 – Jacques 2011-01-09 01:26:54

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); 
}