gpt4 book ai didi

ios - 与 CGContextDrawImage 相比,为什么 UIImageView 如此占用内存

转载 作者:可可西里 更新时间:2023-11-01 04:42:52 25 4
gpt4 key购买 nike

开发 iPad PDF 阅读器时,我们决定准备渲染密集型页面(其中有很多路径)的高分辨率图像,并使用这些图像代替 pdf 页面以避免性能问题。我们认为 3*768 x 3*1024 是可读性和渲染性能之间的一个很好的折衷,这导致 ~1.5 MB jpeg

但是,我们测试了显示图像页面的两种实现方式。一个使用 CATiledLayer 子类,该子类还负责处理“普通”PDF 页面(使用 CGContextDrawImage 绘制),另一个使用 UIImageView。后者的优点是显示和缩放非常快,但内存使用率非常差 - 大约需要 30 MB 内存(这与图像的位图大小一致)。另一种方法 (CATiledLayer) 需要更多时间来首次显示页面,并且在缩放后需要另外两秒钟重新呈现(类似于 pdf 页面,但速度快得多)但不会占用更多内存它需要显示小得多的图像或 PDF 页面。

有谁知道幕后发生了什么,以及是否可以通过使用 Quartz 框架将 CGContextDrawImage 的低内存使用率与 UIImageView 的高性能结合起来。

最佳答案

不确定这个问题是否仍然相关,但如果是这样,也许这会有所帮助:

我在我的 tiled image view 中打过一场有效显示大 View 的战斗。以及。这个问题有很多潜在的部分:

  • 一个普通的 UIView,包括 UIImageView,似乎总是完全由内存支持其图像。即使您实现了 drawRect: 方法,它似乎也总是通过 View 的整个边界,而不仅仅是 ScrollView 中的可见区域。正如您所发现的,这会很快占用很多内存,因为每个像素需要 4 个字节。
  • CATiledLayer确实仅请求可见图 block 的内容。它还会丢弃不再可见的图 block ——这就是内存节省的来源。但是,它在后台线程上执行通知和绘图,同时从白色到内容进行动画处理。它似乎是通过私有(private) API 来实现的,我还没有找到一种方法来将 CATiledLayer 的功能重新实现为我自己的 CALayer 子类,因为看起来很简单不是我们可以作为凡人使用的通知机制。
  • 如果您在 ScrollView 中有多个 View ,它们会在分页时适本地接收到 drawRect: 消息。不过,UIKit 似乎难以处理一个 View 下的太多 subview 。

对于您来说,我可以看到几个可能的选择:

  • 有可能挽救基于CATiledLayer 的实现。 fadeDuration 默认为 0.25 秒,如果您的加载时间很短,这可能会太长。您可以将其降低到 1.0/60.0 之类的值,即一帧。从您的描述中不清楚的一件事是您的图像是覆盖整个页面大小还是仅覆盖每个 256x256 像素的图 block 。为每个图 block 一遍又一遍地解码整个 JPEG 比解码单个图 block 文件要慢得多。
  • 如果从 CATiledLayer 线程执行所有操作的延迟太高,您可以手动创建一堆图 block 作为 UIImageView subview 到空白 UIView 这是 ScrollView 的主要 subview 。这些 subview 中的每一个都分配有自己的平铺图像。如果幸运的话,UIKit 会足够聪明,可以删除这些 View 的内容并根据需要重新加载相应的 JPEG。
  • 如果 UIImageViews 不够智能,或者 UIKit 无法处理的 View 太多,您可以构建自己的 View ,在 drawRect: 中加载它们的 JPEG。如果它仍然太不稳定,请尝试使用您自己的 CALayers,这将是您的单个 View 空白层的子层,并再次按需加载它们的图像。这就是我最终使用的平铺 ImageView 。

这应该包括滚动,但如果您允许用户直接缩小(最小化),它仍然可能非常慢。在这种情况下,我建议您存储适当的低分辨率版本,并以最外层的缩放级别加载/显示这些版本。

关于ios - 与 CGContextDrawImage 相比,为什么 UIImageView 如此占用内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4955458/

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