- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 iPhone 上遇到了 CoreGraphics
/CoreAnimation
的特殊问题。为了更好地解释问题是如何表现出来的,我将向您介绍我当前的设置,并在适当的地方用代码进行说明。
我正在尝试在 UIView
的 CALayer
中绘制一堆预加载的图像,但是每当图像显示时,应用程序的内存使用量就会激增,并且内存不足图像更改时不会回收。
图像的预加载是通过 UIImage
的工具读取它们,将它们渲染到位图上下文并从该上下文中提取 CGImageRef
来完成的。这样做的目的是解压缩和缩放图像,这样这些操作就不会在每次绘制时都发生。在有关此事的 Apple Q&A 中可以找到类似的建议(如果您好奇,请搜索 CGContextDrawImage
performance)。上下文设置为每个分量 8 位和预乘 alpha。
图像解压成位图后,它们存储在 NSArray
中,随后分配(不保留)到执行绘图的自定义 UIView
子类.我尝试了各种方法来实际绘制图像,目前最快的方法是直接设置 View 的 CALayer
contents
属性。 drawLayer:inContext:
和 drawRect:
等其他方法对帧率有不同的影响,但它们都表现出相同的内存行为。
问题是.. contents
属性更改后,我发现 Instruments 中的内存出现峰值,即使图像不再显示,内存也不会下降。对象分配保持不变,所以我唯一的猜测是 CoreAnimation
正在创建一些隐式缓存以加速绘制。然而,正如我所说,该缓存不会在应该释放的时候释放,并且逐渐积累会在运行几分钟后导致崩溃。
contents
属性保留对象,我没有明确释放它,因为我希望原始图像在应用程序执行期间保留在内存中;最重要的是,高保留计数不会解释我看到的内存峰值。
检查堆栈时,我看到 CoreAnimation
调用了诸如 CA::Render::copy_image
之类的函数,这让我相信它正在复制层的内容遥不可及的地方。我想这是有正当理由的,但不知道如何以及何时清除它目前是一个停止显示的错误。
如果我做错了什么,请任何对 CA 有复杂了解的人向我解释,以及我如何解决这种行为。
谢谢。
最佳答案
@CouchDeveloper - 感谢您花时间回复。
我做了一些进一步的挖掘,我会回答我自己的问题而不是直接回复,也许我获得的见解会帮助其他有类似问题的人。
您对分配与内存使用的观察是正确的。我正在查看的内存是内存监视器(事件监视器)工具中应用程序使用的“真实”(常驻)内存。
我想我已经找到了这些神秘内存分配的原因。当 CoreAnimation
遇到不是 native 像素格式的图像时,它会将图像复制到它自己的缓冲区中,这似乎是我所看到的用法。我认为正确的格式是 32 位、主机字节顺序、先预乘 alpha(位图信息标志 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host
)。
为了找出正在复制的 CGImageRef 实例并更广泛地了解框架的内部工作原理,您可以使用设备上的 Core Animation 工具,或指定一些环境变量并从命令启动 iPhone 模拟器-线。可以找到所有标志的列表 here .就我而言,最有用的组合是 CA_COLOR_COPY
和 CA_LOG_IMAGE_COPIES
,这将为复制的图像提供青色覆盖并将副本记录到 stderr。
我仍然遇到一些奇怪的问题(“无数据指针”、非预乘 alpha 等),但我认为这主要是我创建或传递图像的方式的问题,但我认为我在快速解决所有内存问题。
希望这对其他想知道他们的内存和性能问题从何而来的人有所帮助!
关于objective-c - 绘制时的 CALayer 内存使用情况 - 隐式缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3840427/
我是一名优秀的程序员,十分优秀!