【发布时间】:2013-02-20 06:26:20
【问题描述】:
我有一个基于UIDocument 的应用程序,它使用NSFileWrappers 来存储数据。 “主”文件包装器包含许多额外的目录文件包装器,每个包装器代表文档的不同页面。
当保存一个只有一小部分页面被修改的大文档时,UIDocument 会在后台花费很长时间来编写更改(在writeContents:andAttributes:safelyToURL:forSaveOperation:error: 中)。当然,它应该只写出对文件包装器的这一小改动……什么花了这么长时间?
我的contentsForType:error: 覆盖返回一个新的目录文件包装器,其中包含主文件包装器的内容(à la WWDC 2012 Session 218 - Using iCloud with UIDocument):
- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
if (!_fileWrapper) {
[self setupEmptyDocument];
}
return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}
这是来自 Time Profiler 的堆栈跟踪的可爱图片:
顺便说一句,它说要在该工作线程中保存约 1.6 秒 - 在实际运行时间中,这相当于大约 8 秒。
编辑:
有什么方法可以检查文件包装器是否需要写入磁盘?这样我就可以确认,当我做一个小改动时,我并没有做一些奇怪的事情,比如更新每个子文件包装器(尽管我确定我不是......)。
编辑:
我进一步尝试了 CloudNotes 示例应用程序,似乎NSFileWrapper 确实实现了增量保存,至少在这种情况下!我通过初始化一个包含 100 个注释的文档来测试它,每个注释包含大约 5MB 的数据。我在这里和那里做了一个小编辑(文本视图的单个字符更改将文档标记为需要保存),并大致记录了每次保存所用的时间。测试比较粗糙(在模拟器上运行),但结果是这样的:
- 第一次写入:~8000ms
- 第二次写入:~4000ms
- 第三次写入:~300ms
- 所有后续写入:~40ms
显然有很多因素会影响它所花费的时间,特别是因为它是在后台线程中使用文件协调来保存的,但总的来说,趋势似乎总是这种指数衰减,直到所有写入都变得非常快。
但我仍在试图弄清楚为什么这不会在我的应用程序中发生。对于一个大的多页文档(很大,但仍然比我上面执行的 CloudNotes 测试的文档小很多倍),用户可能要等待很多秒才能关闭文档。我不想为应该几乎是即时的事情设置微调器。
【问题讨论】:
-
您是在进行自动保存,还是一次保存所有内容?您是否从主线程启动保存?你是替换每一个 NSFileWrapper,还是只替换那些实际改变的?
-
我完全依赖自动保存,所以保存是由 UIDocument 启动的,通常在写入(后台线程)之前调用
contentsForType:error:(主线程)。我只是替换我已更改的文件包装器(当它们更改时)。但是,我注意到我正在使用一种方法来查看我的所有页面文件包装器并将它们排序为有序数组。我认为这弄乱了 NSFileWrapper 的延迟加载并导致它们需要以某种方式编写。我只是在实现一个索引,这样我就不必这样做了,并且会看到它有什么不同。 -
不,更改为仅使用索引文件来跟踪页面/页码并没有帮助。仍在尝试找出可能导致保存缓慢的原因。
-
你可以加入我的chat here。
-
你有没有发现你到底错过了什么?
标签: ios save uidocument nsfilewrapper