- 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/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!