2

タイトルで述べたように、UIManagedDocument同期的にオープンしたいと考えています。つまり、オープンが完了するまで実行を待機させたいと考えています。mainThread のみでドキュメントを開いています。

ブロックを使用する現在の API を開く

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

リンクで言及されているロックの使用法は、メインスレッド以外のスレッドでもうまく機能します。でロックを使用するmainThreadと、アプリの実行がフリーズします。

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

4

1 に答える 1

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 は素晴らしいです。条件変数アプローチまたは同時キューのバリアの使用は、他のスレッドを使用するときに同期するための合理的な方法です。メイン スレッドの同期は、実行すべきこととは逆です。

頑張ってください...銃を登録し、隠し武器許可証を常に携帯してください。これは確かに野生の西です。銃撃戦を求めているジョン・ウェズリー・ハーデンが常にそこにいます。

于 2012-05-05T13:04:40.787 に答える