我有一个UIDocument
基于 s 的应用程序NSFileWrapper
来存储数据。“主”文件包装器包含许多附加的目录文件包装器,每一个都代表文档的不同页面。
当保存一个只修改了一小部分页面的大型文档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 测试的文档小很多倍),用户可能要等待很多秒才能关闭文档。我不想为应该几乎是即时的事情设置一个微调器。