我在将openWithCompletionHandler:(UIManagedDocument)与主要事件同步时遇到一个基本问题。
情况:
我有一个单例类,用于管理共享的UIManagedDocument。此类提供了一种应以正常状态交付文档的方法(即根据需要创建或打开该文档)。
但是因为openWithCompletionHandler:在后台异步完成其主要工作,所以我的程序应该等待设置fetchedResultsController,直到文档真正打开为止。当数据库尚未准备就绪时,“viewWillAppear”方法(当前)不会产生有用的输出。
等待对我来说还可以,但是通知您可能是更好的方法。也许viewWillAppear并不是setupFetchedResultsController的正确选择,因为它不是在运行循环中调用的。
是否有实现这一目标的标准模式?
更多背景信息(我认为不是那么重要)
我正在研究一个涉及CoreData UIManagedDocument的小iOS 5.1应用程序。
我类似于去年秋天iTunes-U的斯坦福类(class)中第14课中的示例。一切工作正常,直到我尝试将UIManagedDocument的处理从UITableViewController类放到一个单独的类中处理我的文档。
在原始版本中,FetchedResultsController是在完成处理程序中设置的。
最佳答案
我建议遵循Justin Driscoll在Core Data with a Single Shared UIManagedDocument上的出色文章。
您将在UIManagedDocument单例上找到完整的文章,并在performWithDocument上找到示例。您的fetchedResultsController设置代码实际上应该放在performWithDocument:^ {}块中。
另请注意,openWithCompletionHandler并非线程安全的-打开文档时并发调用performWithDocument会导致崩溃。对我来说,解决方案很简单(而且非常特定于应用程序),因此,如果遇到相同的问题,建议您查看UIDocumentStateChangedNotification,它通知文档状态更改,并且可以作为多个文档打开器的同步点。
如果您有兴趣的话,
首先,在MYDocumentHandler的init中,在末尾设置一个附加通知:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(documentStateDidChange:)
name:UIDocumentStateChangedNotification
object:self.document];
然后在performWithDocument中,在关键的打开/创建部分上使用@synchronized(self.document),以确保一次仅进入一个线程,并阻塞其他线程,直到打开/创建成功为止。
最后添加以下功能:
- (void)documentStateDidChange:(NSNotification *)notification
{
if (self.document.documentState == UIDocumentStateNormal)
@synchronized (self.document) {
... unblock other document openers ...
}
}
至于阻塞/解锁线程,YMMV。我使用了dispatch_semaphore_t以及一些dispatch_queues来满足特定于应用程序的要求。您的情况就像等待完成或删除其他线程一样简单。