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

时间:2012-04-01 13:00:09

标签: objective-c concurrency uidocument

我有一个基本的问题,即将openWithCompletionHandler:(UIManagedDocument)与主要活动同步。

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

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

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

1 个答案:

答案 0 :(得分: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];

然后在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来满足特定于应用程序的要求。您的情况可能就像等待完成或丢弃其他线程一样简单。