次のコードでは、アウターループのRunLoopをチェックし、dispatch_afterを使用して内部ループのmain_threadにディスパッチします。私は、これが呼び出される2つのケースを持っています。ひとつは、ナビゲーションバーのボタンが押され、もう一つがviewDidAppearの間です。後でコードを呼び出すと、RunLoopにスタックされたままになり、ブレークポイントは私のdispatch_afterブロックに決してぶつからない。なぜdispatch_afterがブロックされるのですか?コード実行中でもいくつかの進捗インジケータを更新するには、これを行う必要があります。なぜこれがあるケースではうまく動作しないのは明らかですか?私はスタックを見て、そこに他のスタックはあまりありません。メインキューのdispatch_asyncブロックがモーダル実行ループで実行されない
// case 1:
// does not hit breakpoint
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.4 * NSEC_PER_SEC), dispatch_get_main_queue(),^
{
[ self longRunningOp ];
});
// case 2:
// This works fine!
[ self longRunningOp ];
-(void) longRunningOp
{
bool dispatched = false;
while (!finished)
{
if (dispatched)
{
// reusing the same date to avoid buffers building up!
date = [ date initWithTimeIntervalSinceNow:0 ];
[ [ NSRunLoop currentRunLoop ] runMode: NSDefaultRunLoopModes beforeDate:date ];
continue;
}
dispatched = true;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.001 * NSEC_PER_SEC), dispatch_get_main_queue(), ^() {
// In second case breakpoint never gets here!
// OPENGL OPS HERE!
dispatched = false;
}
});
}
他の相違点にも気付きました。
成功事例:それが動作する場合 、UIApplicationMainはCFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTIONに呼び出しを行い、ユーザーがナビゲーションボタンを押したときに、これが起こります。
障害ケース: それが失敗した場合には、UIApplicationMainはCFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUEに呼び出しながら、これはviewDidAppearで発生します。
'longRunningOp'でループを停止するには、' finished'をtrueに設定しますか? 'longRunningOp'はメインスレッドをブロックします。長時間実行される操作は、バックグラウンド・キューにディスパッチする必要があります。 – Paulw11
あなたの正気を保つために、実行ループを操作しないようにしてください。あなたがstackoverflowでそれについての質問をするなら、あなたは本当に実行ループから離れるべきです。 – gnasher729
@ Paulw11 - それは問題だったと思うが、問題はlongRunningOpにさえ達していないということだ。したがって、ブロックはスケジュールされません。この長い実行中のopは、実際にはOpenGLで処理していて、メインスレッド上にある必要があります。しかし、長期的なオペレーションが終わった後であなたの質問に答えることは、終わったと言います。 – nishant