gpt4 book ai didi

objective-c - 绘制时的 CALayer 内存使用情况 - 隐式缓存?

转载 作者:太空狗 更新时间:2023-10-30 03:50:19 25 4
gpt4 key购买 nike

我在 iPhone 上遇到了 CoreGraphics/CoreAnimation 的特殊问题。为了更好地解释问题是如何表现出来的,我将向您介绍我当前的设置,并在适当的地方用代码进行说明。

我正在尝试在 UIViewCALayer 中绘制一堆预加载的图像,但是每当图像显示时,应用程序的内存使用量就会激增,并且内存不足图像更改时不会回收。

图像的预加载是通过 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_COPYCA_LOG_IMAGE_COPIES,这将为复制的图像提供青色覆盖并将副本记录到 stderr。

我仍然遇到一些奇怪的问题(“无数据指针”、非预乘 alpha 等),但我认为这主要是我创建或传递图像的方式的问题,但我认为我在快速解决所有内存问题。

希望这对其他想知道他们的内存和性能问题从何而来的人有所帮助!

关于objective-c - 绘制时的 CALayer 内存使用情况 - 隐式缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3840427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com