【发布时间】:2011-04-19 22:03:06
【问题描述】:
我在 iPhone 上遇到了 CoreGraphics/CoreAnimation 的特殊问题。为了更好地解释问题是如何表现出来的,我将引导您完成我当前的设置,并在适当的地方用代码进行说明。
我正在尝试在UIView 的CALayer 中绘制一堆预加载的图像,但是每当图像显示时,应用程序的内存使用量就会激增,并且每当图像发生变化时,内存都不会被回收。
通过UIImage 的工具读取图像,将它们渲染到位图上下文并从该上下文中提取CGImageRef 来完成图像的预加载。这样做的目的是对图像进行解压缩和缩放,这样这些操作就不会在每次绘制时发生。在 Apple Q&A 中可以找到类似的建议(如果您好奇,请搜索 CGContextDrawImage performance)。上下文设置为每个组件 8 位和预乘 alpha。
图像解压缩为位图后,它们存储在NSArray 中,随后被分配(不保留)给执行绘图的自定义UIView 子类。我尝试了各种方法来实际绘制图像,到目前为止,最快的方法是直接设置视图的CALayercontents 属性。 drawLayer:inContext: 和 drawRect: 等其他方法对帧速率的影响各不相同,但它们都表现出相同的内存行为。
问题是..contents 属性更改后,我看到 Instruments 中的内存出现峰值,即使图像不再显示,内存也不会下降。对象分配保持不变,所以我唯一的猜测是CoreAnimation 正在创建一些隐式缓存以加快绘图速度。然而,正如我所说,缓存并没有在应该释放的时候释放,并且逐渐积累会在运行几分钟后导致崩溃。
contents 属性保留了对象,我没有明确释放它,因为我希望原始图像在应用程序执行期间保留在内存中;最重要的是,高保留计数并不能解释我看到的内存峰值。
在检查堆栈时,我看到CoreAnimation 调用了诸如CA::Render::copy_image 之类的函数,这让我相信它正在将层的内容复制到某个遥不可及的地方。我想这是有正当理由的,但不知道如何以及何时清除它目前是一个令人震惊的错误。
如果我做错了什么,那么任何人都可以向我解释一下我是否做错了什么以及如何解决这种行为。
谢谢。
【问题讨论】:
-
“通过 UIImage 的工具读取它们”到底是什么意思?
-
imageWithContentsOfFile: 或 imageWithData:
-
大家好,让我感到震惊的是,你们对 CALayer 的了解比我更好。我发布了一个 CALayer malloc 问题,如果你们中的任何一个可以看一下,我将非常感激...stackoverflow.com/questions/26715727/…
标签: objective-c cocoa-touch memory core-animation calayer