ios - UIDocument & NSFileWrapper 架构和性能

标签 ios multithreading performance uidocument

我们最近将代码转换为使用 UIDocument 而不是直接在文件系统上操作文件,因此我们遇到了一些性能问题。我们想知道我们是否错误地使用了这个类,是否有其他人遇到过这些问题,以及解决这些问题的常用方法是什么。

我们的应用

我们有一个“鞋盒应用程序”来管理一堆文档,每个文档都包含多个可能非常重的图像文件、一个小的元数据文件和一个小的预览图像。用户的设备上可能有很多文档(1000 多个文档)。每个文档的文件都分组在一个目录中,我们使用 NSFileWrapper 来读取和写入它们。

当我们的应用程序启动时,它需要所有文档的元数据才能显示文档索引和预览图像的子集。用户滚动时会加载更多预览图像。

为了获取该信息,我们打开所有文档,读取它们的元数据并在需要时预览图像,关闭它们,然后根据需要再次打开。

问题 #1:加载时间慢

打开所有文档并读取它们的元数据需要花费大量时间。我认为有几个因素导致了这个问题: - 每个文件打开 Action 比较慢 - 打开文档 block 和完成 block 在同一个队列上执行,这使得操作的延迟非常糟糕(我的文档是打开的,但是完成 block 必须等待X个打开文档 block 才能运行)

我们考虑过使用单独的索引文件来解决这个问题,但这种方法的缺点是我们需要在两个地方管理元数据,并且我们需要保持它与文件系统同步,以防 iCloud 更改索引文件。

问题#2:线程

每个打开的文档都会创建自己的“文件访问线程”。当我们同时打开许多文档时,开销会压垮应用程序。

我们通过使用信号量同步打开操作解决了这个问题。这种方法的缺点是它会进一步减慢加载速度。

问题

  1. 我们使用 UIDocument 的方式是否存在一些根本问题?如果不是:
  2. 有没有人遇到过类似的加载时间问题?常见的解决方法是什么?其他应用程序是否保留索引文件?
  3. 有没有办法让 UI 文档使用线程池?如果不是,您如何控制资源使用?

谢谢!

最佳答案

好的,这里没有好消息。

我们尝试咨询业内 friend ,分析 UIDocument 并使用修改后的实现来改变其操作的各个方面,以查看我们是否可以提高其性能,但无济于事。

我的结论是 UIDocument 不适合这种用途——它的设计目的不是为了支持我们对开放式操作的延迟和吞吐量要求。 UIDocument 只应在您想在任何给定时刻打开少量文件时使用(很像文字处理器和绘图应用程序)。 不可否认,这正是 Apple 的文档所说的,但我想我们必须通过艰难的方式来了解它们的严重性:)

我们最终使用了一些“技巧”来改善用户体验,并将尽快摆脱 UIDocument。

所以我的建议是,只有在:

  1. 您的应用在本质上类似于基于文档的应用,这意味着您在任何给定时刻打开的文档不会超过几个
  2. 您不需要文档中的信息来“发现”它们并将它们展示给用户,或者可以负担管理单独索引文件的开销
  3. 您确实需要此类的自动保存/撤消/同步/iCloud 功能

然后使用它。否则考虑其他解决方案。

附注与问题没有直接关系,但我将在此处添加为公共(public)服务:当我们从直接文件访问转移时,UIDocument 的异步模型需要对应用程序架构进行一些重大更改。如果您计划采取此行动,请仔细评估您需要做的工作。

祝 future 的程序员好运。

关于ios - UIDocument & NSFileWrapper 架构和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23265422/

相关文章:

c# - 在 C# 中将 'using' 与线程实用程序一起使用 - 何时调用 Dispose?

ios - SwiftUI - 检测 ScrollView 何时完成滚动?

JavaFX TableView 没有更新

multithreading - 关于后台线程更新 NSView 的通知

php - 如何非常快速地在字符串中搜索巨型数组的值?

performance - 如何对我的 Web 应用程序进行容量规划并决定部署架构?

arrays - 在 Python 中乘以矩阵数组的最快方法(numpy)

iOS:自定义对象的 int 变量在 NSUserDefaults 中返回 nil

ios - 如何取消 iOS 中的完成处理程序

ios - 尝试提交带有 Siri 扩展的应用程序时,来自 App Store 的错误 "Invalid Intent Vocabulary"