【发布时间】:2014-12-06 07:00:53
【问题描述】:
我的 UITableView 出现平滑滚动问题,其中包含 UIImageView 的 UITableViewCell。在整个 StrackOverflow 中都可以找到类似的问题,但没有一个建议的解决方案可以帮助我完全摆脱滞后。
我的情况很常见:
- 图像存储在应用程序存储中(在我的应用程序包示例中)
- 图片可以有不同的尺寸(500x500、1000x1000、1500x1500)
- 我需要在 UIImageView 大小为 120x120(视网膜)的 UITableView 中显示这些图像
我遵循了多个优化技巧并设法优化了很多滚动。 不幸的是,它仍然不完美。这是我的场景:
- 首先我将所有图像加载/处理/调整大小逻辑移至后台线程
- UITableViewCell 重用已启用
- 一旦 UITableViewCell 在视图中,我清除旧值(设置为 null)并启动后台线程以加载图像
- 此时我们处于后台线程中,我添加了 500 毫秒的延迟以避免经常设置新图像(以防我们快速滚动)(见下文说明)
- 如果 UIImage 存在于静态图像缓存中(带有 UIImage 实例的常规字典) - 获取该缓存并转到第 9 步。
- 如果不是 - 使用 url 从包 (imageWithName) 加载新图像到应用包(在现实世界场景中,图像将存储到应用程序存储,而不是包)
- 加载图像后,使用图形上下文将其大小调整为 120x120
- 将调整大小的图片保存到静态图片缓存中
- 此时我们有 UIImage 的实例,并且进程在后台线程中。从这里我们回到给定图像的 UI 线程
- 如果数据上下文被清除(例如 UITableViewCell 消失或被重新用于显示另一个图像),我们将跳过当前可用图像的处理。
- 如果数据上下文相同 - 使用 alpha 动画 (UIView.Animate) 将 UIImage 分配给 UIImageView
- 一旦 UITableViewCell 不在视野范围内 - 清除数据上下文
最初在启动新的后台线程以在此处获取图像之前(第 1 步)是没有后台线程的 UIImage 缓存检查。在这种情况下,如果我们在缓存中有图像,我们会立即分配它,这会在快速滚动期间引入很大的延迟(只要我们立即获取图像,我们就经常分配图像)。这些行在我下面附加的示例中进行了注释。
还有两个问题:
- 在滚动过程中的某个时刻,我仍然有一点延迟(在 当我将新的 UIImage 分配给 UIImageView 时。
- (这个更明显)当您点击项目并从详细信息返回时,在返回导航动画完成之前会有一个延迟。
感谢任何建议如何处理这两个问题或如何优化我的方案
请考虑用 Xamarin 编写的示例,但我不认为 Xamarin 是问题的原因,只要我对用 ObjectiveC 编写的应用程序也有同样的问题。
【问题讨论】:
-
我很想看看这个项目,但我使用的是 xCode。有什么方法可以转换吗?
-
Instruments(或 Xamarin 等价物)告诉您有关应用程序性能的哪些信息?你在哪里度过你的时间?是 CPU 限制还是 GPU 限制?等
-
您似乎没有使用 CoreData。可能会测试在 CoreData TableView 中显示缩略图是否不会提高内存管理和缓存性能。
-
@carlodurso 它被一对一映射到objectiveC
-
@DavidRönnqvist 仪器显示活动的正态分布(时间测量)。如何衡量“是受 CPU 限制还是受 GPU 限制?”
标签: ios uitableview uiimage xamarin smooth-scrolling