ios - 由于异常内存使用,启用 CATiledLayer 的 UIView(具有 drawRect 定义的 subview )崩溃

标签 ios ipad uiview catiledlayer

iPad 3 上发生内存不足崩溃,我们追踪到以下情况:

使用 CATiledLayer 并绘制内容(例如 PDF)的 UIView 具有带有自己的 drawRect 方法的 subview (例如,突出显示搜索结果)。这使得 Core Animation 消耗大量内存(VM Tracker 工具中超过 100 MB),并且很容易导致崩溃。虽然所有设备上都存在此问题,但只有 iPad 的 Retina 显示屏上缓存大小会变得过大。

这可以用 Apple 的 PhotoScroller 来重现示例:子类 UIView,取消注释 drawRect,并向 TilingView 添加一个实例。该应用程序将在 iPad 3 上崩溃。注释 drawRect 可以解决内存使用问题。

现在,我们可以删除 subview 并在最顶层的 UIView 中进行绘制。然而,使用 subview 很方便(因为我们在 PDF 之上表示不同的、独立的层)。两个问题:

  1. 什么是好的解决方法?最好是允许我们继续使用多个 View 的工具。
  2. 到底为什么会发生这种情况?我猜缓存机制正在超时工作,但了解其背后的技术细节会很棒。

谢谢!

编辑:

我想详细说明凯的回答。该问题确实与CATiledLayer无关,而是与实现drawRect的UIView的使用有关。

就 PhotoScroller 而言,我创建了一个 UIView,其大小与图像大小相同 - 2000x2000 甚至更多,如果存在drawRect,它会创建一个巨大的后备存储。

就我们的应用而言,覆盖 View 是全屏的(iPad 3 上约为 11 MB),每页大约有 5 个。滚动时我们在内存中保留最多三页,这意味着超过 150 MB 的额外内存。不好玩。

所以解决方案是优化drawRect,或者少用这样的 View 。回到绘图板,它是:-)

最佳答案

至 2.:每当您在 UIView 子类中实现 drawRect 并拥有该类的大量实例时,您的内存使用量就会急剧增加。原因是 UIKit View / subview 处理(例如缩放或滚动时)中的许多优化技巧不适用于此类对象,因为框架不知道您在做什么/做什么你正在画画。 因此,无论是否与视网膜无关,都要避免实现drawRect,特别是当有许多对象或多层 subview 时。

至 1.:我没有完全明白你正在尝试的内容,但我实现了一个 PDF 查看器,它也能够在 PDF 之上显示附加内容。我用正常的 UIView 层次结构、图像等完成了这一切,我担心这是您能得到的唯一可靠的工作

关于ios - 由于异常内存使用,启用 CATiledLayer 的 UIView(具有 drawRect 定义的 subview )崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10384383/

相关文章:

ios - 保持网络事件指示器旋转

iphone - 如何在他们的时钟应用程序中实现 Apple 的 "Snooze"功能?

ios - 如何为 iPad 应用程序添加条码阅读器功能?

ios - 在键盘上方显示 UIView 无法正常工作

objective-c - 快速将图像从 View Controller 传递到 UIview

ios - 我如何在 iOS 中实现 Payeezy 定期基本付款?

ios - 如何在 objective-c 中从NSDictionary获取UIImage

ios - 当第一次设置里面的 imageView 时,自调整单元格没有更新它的高度

iOS 7 在单线程安全上没有合并冲突

ios - UIView 当它是 tableHeaderView 时更新,但当它是 subview 时不更新