5

openWithCompletionHandler: (UIManagedDocument) をメインのアクティビティと同期する際に基本的な問題があります。

状況: 共有 UIManagedDocument を管理するシングルトン クラスがあります。このクラスは、ドキュメントを通常の状態で配信するメソッドを 1 つ提供します(つまり、必要に応じてドキュメントを作成または開きます)。しかし、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 で、重要な open/creation セクションで @synchronized (self.document) を実行して、一度に 1 つのスレッドのみが入るようにし、open/creation が成功するまでそれ以上のスレッドをブロックします。

最後に次の関数を追加します。

- (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 に答える