ios – 为什么Apple建议在串行后台队列中调度OpenGL命令,这不可避免地会导致崩溃?

他们 suggest

When using GCD,use a dedicated serial queue to dispatch commands to
OpenGL ES; this can be used to replace the conventional mutex pattern.

我不明白这个建议.我无法解决这种冲突:

当应用程序的app委托收到-applicationWillResignActive调用时,它必须立即停止调用任何OpenGL函数.

如果应用程序在-applicationWillResignActive返回后继续调用OpenGL函数,则应用程序将崩溃.

如果我遵循Apple的建议在串行后台队列中调用OpenGL函数,我面临着这个看似无法解决的问题:

1)收到-applicationWillResignActive后,我必须立即停止调用任何进一步的OpenGL函数.

2)但是因为串行队列正在处理后台代码块的过程中,有时代码块会在-applicationWillResignActive返回后完成执行,并且应用程序崩溃.

这是显示并发“块”的图示.主线程收到一个完整的停止消息,并且必须阻止进一步调用OpenGL ES.但不幸的是,这些发生在后台队列中,无法在块上工作时停止:

|_____main thread: "STOP calling OpenGL ES!"_____|
 _____|_____drawing queue: "Draw!"_____|_____drawing queue: "Draw!"_____|

从技术上讲,我发现无法立即停止后台队列,并避免在后台进一步调用OpenGL.一旦运行,提交的代码块将继续运行.

我找到的唯一解决方案是不在后台调用OpenGL ES函数.相反,在主线程上调用它们以保证在应用程序失去对GPU的访问权限之后永远不会调用它们.

因此,如果可以在后台调用OpenGL ES函数,那么在应用程序重新激活后,如何确保它们永远不会被调用

解决方法

只需在applicationWillResignActive中等待队列使用调度组或类似机制完成所有排队操作.

您可以在documentation中找到一个示例:

dispatch_queue_t queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();

// Add a task to the group
dispatch_group_async(group,queue,^{
   // Some asynchronous work
});

// Do some other work while the tasks execute.

// When you cannot make any more forward progress,// wait on the group to block the current thread.
dispatch_group_wait(group,disPATCH_TIME_FOREVER);

// Release the group when it is no longer needed.
dispatch_release(group);

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...