Ios 如何拆除GCD队列?

Ios 如何拆除GCD队列?,ios,opengl-es,concurrency,grand-central-dispatch,Ios,Opengl Es,Concurrency,Grand Central Dispatch,我有一个GCD绘图队列来更新我的OpenGL ES场景,其结构如下: - (void)drawFrame { dispatch_async(drawingQueue, ^{ if (dispatch_semaphore_wait(frameRenderingSemaphore, DISPATCH_TIME_NOW) != 0) { return; } @autoreleasepool { [

我有一个GCD绘图队列来更新我的OpenGL ES场景,其结构如下:

- (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绘图运行循环

然而,问题是dispatch_asyn即使在CADisplayLink失效之前也会发送图形块。当用户按下home按钮时,我的应用程序崩溃,因为它试图在OpenGL中绘制一个框架,即使iOS已经破坏了上下文


有没有一种方法可以终止/暂停GCD队列,使其不再分派任何内容?

我认为最简单的方法是在应用程序中设置一个标志,在执行块之前检查该标志。例如:

- (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);
    });
}
您可以在
applicationIdentinterbackground
applicationWillTerminate
中的应用程序委托中设置这些值

您也可以尝试以下方法:

dispatch_suspend(drawingQueue);
dispatch_release(drawingQueue);
不过我不太确定


以下是所有详细信息:

分派\u挂起
将阻止额外排队的作业开始,但对当前运行的作业不执行任何操作。(我不知道这两种情况中的哪一种适用于这里。)除了Simon的建议之外,我可能会指出您的
dispatch\u semaphore\u wait()
位于错误的位置。它需要在
调度\u async()
之前,而不是在异步块中。使用这样的信号量的全部原因是为了防止在GCD队列中一次添加多个渲染块,而在应用程序进入后台后看到渲染帧的原因是因为队列中堆积了大量渲染帧。我敢打赌,当您将等待移到异步调度之前,您会发现这种崩溃消失。
dispatch\u release
只会减少队列的保留计数,允许在保留计数达到零时将其释放,因此这不太可能有助于iFrog
dispatch\u suspend
更有希望,但这取决于块是否已在运行。(如果还没有运行,上面的解决方案可能更简单。)谢谢!向上投票需要15个声望。本来可以做到的:-)你现在应该可以做到了