我一直在阅读有关UIDocument和UIManagedDocument的所有内容,因为UIManagedDocument上有更多帮助,它是UIDocument的子类,但我无法弄清楚我需要做些什么。
当用户点击我的应用的添加按钮来创建新文档时,我需要创建文档并预先填充几个项目。只要我单步执行调试器,我执行此操作的代码就可以正常工作,但是在全速运行时,这些项目不会进入文档。
我在AppDelegate中存储了对文档的引用,并为代码中的简化读取定义了一个宏:
#define SelectedDocument [(AppDelegate *)[[UIApplication sharedApplication] delegate] selectedDocument]
因此,在处理添加请求时,我的代码执行此操作:
GnKDocument *tmp = [[GnKDocument alloc] initWithFileURL:fileURL];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setSelectedDocument:tmp];
[SelectedDocument saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if (success) {
[SelectedDocument openWithCompletionHandler:^(BOOL success) {
if (success) {
[SelectedDocument setDateCreated:[NSDate date]];
NSString *c1UUID = [SelectedDocument appendChapterWithName:@"Chapter 1"
withColor:kChapterColorYellow];
NSString *p1c1UUID = [SelectedDocument appendPageWithParent:c1UUID
withName:@"Page 1"
withColor:kPageColorRed];
NSLog(@"Just added Page 1 as %@ to chapter %@", p1c1UUID, c1UUID);
[SelectedDocument closeWithCompletionHandler:^(BOOL success) {
}];
}
}
}];
对我的UIDocument子类的两个追加调用完成他们的工作,然后调用
[self updateChangeCount:UIDocumentChangeDone];
作为测试步骤,我会覆盖该方法只是为了注销正在进行的更改:
- (void)updateChangeCount:(UIDocumentChangeKind)change
{
[super updateChangeCount:change];
NSLog(@"GnKDocument recording a change");
}
我是按正确的顺序做事吗?我应该将呼叫分配到各种队列吗?
同样,如果我在每次调用时设置断点(saveToURL:,openWithCompletionHandler:和closeWithCompletionHandler)并“跳过”这些调用,然后运行进入完成处理程序,文档最终会按照我的意图进入磁盘。如果我禁用断点并再次运行,则会在磁盘上创建文档并记录更改,但关闭的文件不包含我的两个初始元素。
答案 0 :(得分:0)
在最长的时间里,我认为差异在于代码执行的速度是创建还是避免竞争条件。但在调查这种可能性的过程中,我在各地都添加了许多关键事件......并且问题消失了。所以它显然不是时间问题。回顾一下NSLog语句的内容,我意识到一些值是延迟加载的,并且在NSLog语句中引用它们的行为导致它们被加载。同样,在单步执行代码时,我怀疑“打印描述...”命令具有相同的效果(可能)。
所以在我的例子中,UIDocument子类构建了一个包含两个文件的文件包装器,一个用于文档的元数据,另一个用于实际的文档数据。有一个测试来验证文档中的最小正确性,并且此测试使用了元数据文件中的值,这些值意味着延迟加载但从未被访问过,因此测试确定文件无效并设置初始值全部再次,擦除了我正在准备文件的两个项目。