iOS5.1:同步任务(等待完成)

tsc*_*oss 5 concurrency objective-c uidocument

我有一个基本问题是将openWithCompletionHandler:(UIManagedDocument)与主要活动同步.

情况:我有一个管理共享UIManagedDocument的单例类.此类提供其中应递送一种方法在正常状态下的文档(即,创建或打开它,无论是neccessary).但是因为openWithCompletionHandler:它在后台异步执行它的主要工作,我的程序应该等待设置fetchedResultsController直到文档真的打开.当数据库未准备好时,"viewWillAppear"方法(当前)不会产生有用的输出.等待对我来说没问题,但收到通知可能是更好的方法.也许viewWillAppear不是setupFetchedResultsController的正确点,因为没有在runloop中调用.

是否有标准模式来实现这一目标?

更多的背景(我认为不是那么重要)我正在开发一个涉及CoreData UIManagedDocument的iOS 5.1应用程序.我类似于去年秋天在iTunes-U的斯坦福大学课程第14课的例子.一切都工作正常,直到我试图将UIManagedDocument的处理从UITableViewController类转移到处理我的文档的单独的类.在原始版本中,FetchedResultsController在完成处理程序中设置.

Eri*_*hen 3

我建议遵循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];
Run Code Online (Sandbox Code Playgroud)

然后在performWithDocument中,在关键的打开/创建部分上@synchronized (self.document),以确保一次只有一个线程进入,并阻塞其他线程,直到打开/创建成功。

最后添加如下函数:

- (void)documentStateDidChange:(NSNotification *)notification
{
    if (self.document.documentState == UIDocumentStateNormal)
        @synchronized (self.document) {
            ... unblock other document openers ...
        }
}
Run Code Online (Sandbox Code Playgroud)

至于阻塞/解除阻塞线程,YMMV。我使用了dispatch_semaphore_t和一些dispatch_queues来满足特定于应用程序的要求。您的情况可能很简单,例如等待完成或删除其他线程。