Stu*_*art 8 save nsfilewrapper ios uidocument
我有一个UIDocument基于应用程序,使用NSFileWrappers来存储数据.'master'文件包装器包含许多其他目录文件包装器,每个包装器代表文档的不同页面.
保存仅修改了一页的一小部分的大型文档UIDocument时,在后台花费很长时间写入更改(in writeContents:andAttributes:safelyToURL:forSaveOperation:error:).当然它应该只写出这个文件包装器的一个小改动......什么花了这么长时间?
我的contentsForType:error:覆盖返回一个新的目录文件包装器,其中包含主文件包装器的内容(例如,WWDC 2012会话218 - 使用带有UIDocument的iCloud):
- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
if (!_fileWrapper) {
[self setupEmptyDocument];
}
return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}
Run Code Online (Sandbox Code Playgroud)
这里是Time Profiler的堆栈跟踪的可爱图片:

顺便提一下,它表示要保存的工作线程约为1.6s - 在实际运行时间内,这相当于大约8秒.
编辑:
有什么方法可以检查文件包装器是否需要写入磁盘?正因为如此,我可以确认我做某些奇怪的事情,比如当我做一个小改动时更新每个子文件包装器(尽管我确定我不是......).
编辑:
我进一步使用了CloudNotes示例应用程序,看起来NSFileWrapper 确实实现了增量保存,至少在这种情况下!我通过初始化一个包含100个音符的文档来测试它,每个音符包含大约5MB的数据.我在这里和那里做了一个小编辑(文本视图的单个字符更改将文档标记为需要保存),并大致记录每次保存所花费的时间.测试相对粗糙(并在模拟器上运行),但结果是这样的:
显然有很多因素会影响它所花费的时间,特别是因为它在后台线程中使用文件协调来节省,但总的来说趋势似乎总是这种指数衰减,直到所有写入变得非常快.
但我仍然想弄清楚为什么这不会发生在我的应用程序中.对于大型多页文档(大型,但仍然比我上面执行的CloudNotes测试的文档小很多倍),用户可以等待很多秒才能关闭文档.我不想把旋转器放在一个应该是瞬间的东西上.
NSFileWrapper实际上是将整个文档加载到内存中。因此UIDocument,对于大文档来说,使用 anNSFileWrapper实际上并不好。该文档让您认为它可以进行增量保存,但就我而言,它似乎并没有这样做。
UIDocument不限于NSFileWrapper或NSData。您可以使用自己的自定义类,只需重写某些方法即可。我最终编写了自己的文件包装类,该类仅引用磁盘上的文件并按需读取/写入单个文件。
这是我的UIDocument类使用自定义文件包装器的样子:
@implementation LSDocument
- (BOOL)writeContents:(LSFileWrapper *)contents
andAttributes:(NSDictionary *)additionalFileAttributes
safelyToURL:(NSURL *)url
forSaveOperation:(UIDocumentSaveOperation)saveOperation
error:(NSError *__autoreleasing *)outError
{
return [contents writeUpdatesToURL:self.fileURL error:outError];
}
- (BOOL)readFromURL:(NSURL *)url error:(NSError *__autoreleasing *)outError
{
__block LSFileWrapper *wrapper = [[LSFileWrapper alloc] initWithURL:url isDirectory:NO];
__block BOOL result;
dispatch_sync(dispatch_get_main_queue(), ^(void) {
result = [self loadFromContents:wrapper
ofType:self.fileType
error:outError];
});
[wrapper loadCache];
return result;
}
@end
Run Code Online (Sandbox Code Playgroud)
我使用它作为基类并将其子类用于其他项目。它应该让您了解如何集成自定义文件包装类。
| 归档时间: |
|
| 查看次数: |
2837 次 |
| 最近记录: |