2012-04-25 1 views
2

タイトルに記載されているとおり、私はUIManagedDocumentを同期して開こうとしています。つまり、私の実行がオープン完了まで待つようにしたいと思います。私はmainThread上でのみドキュメントを開きます。用途がメインスレッド以外のスレッドでもlink作品に言及したUIManagedDocumentを同期して開く/作成する方法は?

[UIManagedDocument openWithCompletionHandler:(void (^)(BOOL success))]; 

ロックの使用をブロック開くため

現在のAPI。 mainThreadでロックを使用すると、アプリの実行がフリーズします。

アドバイスが役に立ちます。ありがとう。

答えて

2

まず、は、これを行うことを強くお勧めします。あなたのメインスレッドは待っていて、呼び出しが完了するのを待っている間は何もしません。特定の状況下では、メインスレッドで応答しない場合、システムはあなたのアプリケーションを終了させます。これは非常に珍しいことです。

さまざまなプログラミングツールをいつどのように使用すべきかを決めるにはどうすればよいでしょうか。

これは、あなたが望むものをまったく実行します。完了ハンドラが実行されるまでメインスレッドをブロックします。繰り返しますが、私はこれを行うことはお勧めしません、ちょっと、それはツールだ、と私はNRAのスタンスを取るよ:銃が人を殺すことはありません...

__block BOOL waitingOnCompletionHandler = YES; 
[object doSomethingWithCompletionHandler:^{ 
    // Do your work in the completion handler block and when done... 
    waitingOnCompletionHandler = NO; 
}]; 
while (waitingOnCompletionHandler) { 
    usleep(USEC_PER_SEC/10); 
} 

別のオプションは、実行を実行することですループ。しかし、実際には同期ループではありません。実行ループが実際に他のイベントを処理するためです。私はいくつかの単体テストでこの手法を使用しました。これは上記と似ていますが、メインスレッド上で他のものが発生することを許可します(たとえば、完了ハンドラが前のメソッドで実行されないメインキュー上の操作を呼び出す可能性があります)。

__block BOOL waitingOnCompletionHandler = YES; 
[object doSomethingWithCompletionHandler:^{ 
    // Do your work in the completion handler block and when done... 
    waitingOnCompletionHandler = NO; 
}]; 
while (waitingOnCompletionHandler) { 
    NSDate *futureTime = [NSDate dateWithTimeIntervalSinceNow:0.1]; 
    [[NSRunLoop currentRunLoop] runUntilDate:futureTime]; 
} 

は、他の方法がありますが、これらは、理解しやすい、シンプルであり、それはあなたが非正統的な何かをやっている知っていることは簡単ですので、痛み親指のように突き出し。

私はテスト以外でこれを行う良い理由に遭遇したことはありません。あなたはコードをデッドロックすることができますし、メイン実行ループから戻ってくるのは滑らかなものではありません(あなたが手動で実行していても - ループを再び実行してコードを再入力するか、いくつかの他の問題)。

非同期APIは優れています。条件変数アプローチまたは並行キューの障壁の使用は、他のスレッドを使用するときに同期する合理的な方法です。メインスレッドを同期させることは、実行しなければならないことの反対です。

幸運を祈る...あなたの銃を登録し、常にあなたの秘密の武器許可を持っていることを確認してください。これは確かに野生の西です。銃撃戦を探しているジョン・ウェズリー・ハーデンがいつもあります。

+0

...ありがとうございます。ブロックを使わずに古いAPIオープンドキュメントを検索しようとしました。どんなアイデアでも、どのように達成されましたか? –

+1

UIManagedDocumentは比較的新しいインターフェイスであり、同期APIを持っていたとは思いません。内部には、2つのManagedObjectContextオブジェクトがあります.1つはメインスレッドに、もう1つはプライベートディスパッチキューを使用します。すべてのIO操作はバックグラウンドで行われるため、クラスの性質上、非同期APIを使用する必要があります。ブロックの前に、非同期APIは、操作が完了したときに呼び出し元に通知するためにデリゲートまたは通知を使用しました。 –

+1

これは動作しません。以下のコードを試してみてください。 __block BOOL waitingOnCompletionHandler = YES; [_managedDocument openWithCompletionHandler:^(BOOL成功){ if(成功){ DLog(@ "オープンドキュメントが成功!"); self.managedObjectContext = _managedDocument.managedObjectContext; waitingOnCompletionHandler = NO; } }]; while(waitingOnCompletionHandler){ usleep(USEC_PER_SEC/10); } メインスレッドがそこに残っています... – zolibra

関連する問題