1

次のような構造の OpenGL ES シーンを更新するための GCD 描画キューがあります。

- (void)drawFrame {
    dispatch_async(drawingQueue, ^{
        if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) {
            return;
        }

        @autoreleasepool {
            [self startDrawing];

            // drawing code

            [self endDrawing];
        }

        dispatch_semaphore_signal(frameRenderingSemaphore);
    });
}

アプリがアクティブでなくなるかバックグラウンドに入ると (両方)、CADisplayLink を無効にして OpenGL 描画実行ループを停止します。

ただし、問題は、CADisplayLink が無効になるまで、dispatch_asyn が描画ブロックをディスパッチすることです。ユーザーがホーム ボタンを押すと、iOS が既にコンテキストを破棄しているにもかかわらず、OpenGL でフレームを描画しようとしたため、アプリがクラッシュします。

GCD キューを強制終了/一時停止して、何もディスパッチしないようにする方法はありますか?

4

1 に答える 1

2

最も簡単な方法は、ブロックを実行する前にチェックするフラグをアプリケーションに設定することだと思います。例えば:

- (void)drawFrame {
    dispatch_async(drawingQueue, ^{

        if (appIsTerminated || appIsInBackground) {
            return;
        }

        if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) {
            return;
        }

        @autoreleasepool {
            [self startDrawing];

            // drawing code

            [self endDrawing];
        }

        dispatch_semaphore_signal(frameRenderingSemaphore);
    });
}

これらの値は、applicationDidEnterBackgroundおよびのアプリ デリゲートで設定できますapplicationWillTerminate

これを試すこともできます:

dispatch_suspend(drawingQueue);
dispatch_release(drawingQueue);

しかし、それらについてはよくわかりません。

詳細は次のとおりです: https://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

于 2012-10-05T14:48:04.120 に答える