0

私はこれに完全に固執しています。私の基本的な問題は、次のことです。

   - (NSFetchedResultsController *)fetchedResultsController

managedObjectContext / UIManagedDocumentがnilであるため、コアコアエンティティを読み取ろうとするとメソッドがクラッシュします。現時点では、UIManagedDocumentが開いていない/準備ができていないことが原因だと思います。そのため、過去3時間、ドキュメントが開かれるまでデリゲートメソッドが起動されないように作成しようとしています。

これは、ドキュメントを取得するために使用しているコードです。

      if (!self.document) {
    [[CATManagedDocumentHandler sharedDocumentHandler] performWithDocument:^(UIManagedDocument *document) {
        self.document = document;         
    }];
} 

これは私のアプリの他の場所では問題なく機能しますが、テーブルビューのデリゲートメソッドに対して開くプロセスが十分に速くないようです。

私がこれまでに見たリンク:

http://omegadelta.net/2011/05/10/how-to-wait-for-ios-methods-with-completion-blocks-to-finish/

@selectorの代わりにコードブロックを実行する

dispatch_queue_tとdispatch_syncの呼び出しについて

グランドセントラルディスパッチ(GCD)とperformSelector-より良い説明が必要

メインスレッドでタスクを実行するGCD

iOS-スレッド(GCDを使用)がジョブを終了したときに通知を受ける方法

私は試しました:NSNotification(CATManagedDocumentHandlerで設定)を取得するまでメインスレッドをブロックし、ブロックコールバックを取得するまでメインスレッドをブロックします。

これらはどちらも機能しません。アプリがフリーズします。私はこれについて間違って考えていますか?ドキュメントが開く/準備ができるまでデリゲートメソッドを待機させるにはどうすればよいですか?それとも、これで取るべき別のアプローチがありますか?

ありがとう

カール。

4

1 に答える 1

0

わかりました。アプリを最初に起動するときに、1。データベースが存在するか(存在しない場合は初期化する)、2。ドキュメントが(ディスク上に)存在しないか、閉じているか開いているかを確認することをお勧めします。 。

これを行う方法は次のとおりです。

データベースにシングルトンを使用しているように見えるので、最初のView Controllerが起動したら、管理対象ドキュメントが割り当てられているかどうかを確認します。ViewWillAppearで次のようになります。

if (!dataBase)
{
        NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        url = [url URLByAppendingPathComponent:@"Your DB Name"];
        self.dataBase=[[UIManagedDocument alloc]initWithFileUrl:url];
}

したがって、データベース(UIManagedDocument)が割り当てられている場合でも、実際のデータベースファイルがディスク上に作成されていることを意味するわけではありません。次のようにチェックする必要があります(データベースのセッターまたはViewDidLoadでこれを行うことはできますが、機能しないため、別のスレッドでは行わないでください)

したがって、ここで3つのケースをチェックしています:存在しません

if (![[NSFileManager defaultManager]fileExistsAtPath:[yourManagedDocumentFromSingleton.fileUrl path])
{
   [[NSFileManager defaultManager]fileExistsAtPath:[yourManagedDocumentFromSingleton saveToUrl:[[NSFileManager defaultManager]fileExistsAtPath:[yourManagedDocumentFromSingleton.fileUrl forSaveOperation:UIDocumentSaveForCreating completionHandler: 
^(BOOL success){ now you can use your uidocument and its managed object context}];
    }

ファイルは存在するが閉じられている場合:

else if (yourManagedDocumentFromSingleton.documentState==UIDocumentStateClosed)
{
[yourManagedDocumentFromSingleton openWithCompletionHandler:
^(BOOL success) {use your document here}];
}

最後に、ドキュメントがすでに開いている場合は、それを使用します。

else if (yourManagedDocumentFromSingleton.documentState=UIDocumentStateNormal)
{
//do whatever with the document
}

言及すべき重要なことの1つは、UIDocumentはスレッドセーフではないということです。したがって、作成されたのと同じスレッド(おそらくここではメインスレッド)で使用およびチェックする必要があります。そうしないと動作しません。

ビューコントローラまたはシングルトンの正確な構造はわかりませんが、これらの手順に従うと機能します。

PS。また、ドキュメントが起動して実行され、アイテムを追加または削除する場合は、操作のたびにドキュメントを保存して、NSFetchedResultsControllerが更新されるようにしてください。CoreDataには自動保存機能がありますが、正しく機能させるには手動で保存する必要があることがわかりました。(以前の方法から)で保存できます:

forSaveOperation:UIDocumentSaveForOverwriting
于 2012-12-08T17:03:39.297 に答える