5

我在将 openWithCompletionHandler: (UIManagedDocument) 与主要活动同步时遇到了一个基本问题。

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

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

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

4

1 回答 1

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

于 2012-04-27T02:48:12.110 回答