UIDocument&NSFileWrapper体系结构和性能

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

我们的应用

我们有一个“shoebox应用程序”,用于pipe理一系列文件,每个文件都包含多个可能相当重的图像文件,一个小的元数据文件和一个小的预览图像。 用户可能在设备上有多个文档(超过1000个文档)。 每个文档的文件分组在一个目录中,我们使用NSFileWrapper来读写它们。

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

为了获取这些信息,我们打开所有的文档,阅读他们的元数据和预览图像,如果需要的话,closures它们,然后再次打开。

问题1:加载速度慢

打开所有文档并阅读其元数据需要很长时间。 我认为这个问题有几个原因: – 每个文档的打开动作相对较慢 – 打开的文档块和完成块在同一个队列上执行,这使得操作的延迟非常糟糕(我的文档是打开的,但是完成块必须等待X打开文档块才能运行)

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

问题#2:线程

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

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

问题

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

谢谢!

好的,这里没有好消息。

我们试着咨询业内的朋友,分析UIDocument,并使用修改后的实现来改变其操作的各个方面,以便看看我们是否能够改善其性能,但无济于事。

我的结论是,UIDocument不适合这种用法 – 它只是没有devise来支持我们的开放操作的延迟和吞吐量要求。 UIDocument只能用于在任何特定时刻打开less量文件(很像文字处理器和绘图应用程序)。 无可否认,这正是苹果公司的文档所说的,但我想我们必须学习他们是多么严肃的方式:)

我们最终使用了一些“技巧”来改善用户体验,并尽快从UIDocument中移除。

所以我的build议是只有在以下情况下:

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

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

一个附注与问题没有直接关系,但我将在这里添加为公共服务:当我们从直接文件访问转移时,UIDocument的asynchronous模型需要对应用程序体系结构进行一些重大更改。 如果您打算采取这一举措,请评估您需要认真做的工作。

祝你未来的程序员好运。

文档类具有asynchronous读取的方法。 有你的尝试吗?

这听起来像是更适合Core Data或SQLite的元数据。 至less,将核心数据中的元数据caching(整个应用程序的单个存储区,而不是每个文档一个)。