在 GLKView 之上修改 UIVIew 导致崩溃
Modifying UIVIew above GLKView causing crashes
我的应用程序随机崩溃。最终我发现当我添加 UIVIew 元素并修改它们的中心位置时会发生崩溃。 IPad Air 2 上没有发生崩溃,但 IPad Air 上的情况是一致的 - 当 UIViews 打开时,会发生崩溃,当视图被移除时崩溃会消失。崩溃与以下堆栈异步发生:
#0 0x0000000190bf1f28 in gpus_ReturnGuiltyForHardwareRestart ()
#1 0x0000000190bf2ec4 in gpusSubmitDataBuffers ()
#2 0x0000000189d56254 in gliPresentViewES_Exec ()
#3 0x0000000189d5616c in gliPresentViewES ()
#4 0x0000000189d63cbc in -[EAGLContext presentRenderbuffer:] ()
#5 0x0000000101ff8078 in EAGLContext_presentRenderbuffer(EAGLContext*, objc_selector*, unsigned long) ()
#6 0x00000001877dc638 in -[GLKView _display:] ()
#7 0x000000018b55eeb8 in CA::Layer::display() ()
#8 0x000000018b5413a0 in CA::Layer::display_if_needed(CA::Transaction*) ()
#9 0x000000018b54108c in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#10 0x000000018b54071c in CA::Context::commit_transaction(CA::Transaction*) ()
#11 0x000000018b540470 in CA::Transaction::commit() ()
#12 0x000000018b539c10 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#13 0x000000018666f3f8 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#14 0x000000018666d19c in __CFRunLoopDoObservers ()
#15 0x000000018666d5cc in __CFRunLoopRun ()
#16 0x000000018659d280 in CFRunLoopRunSpecific ()
#17 0x00000001915500cc in GSEventRunModal ()
#18 0x000000018bd8adf8 in UIApplicationMain ()
#19 0x000000010077d36c in main at /Code/splinedr/Splinedr/main.mm:18
#20 0x000000019b7fa8b8 in start ()
我使用调用 [self.view needDisplay]
渲染 OpenGL 并在此之前修改 UIViews。
我该如何处理这个问题?
确保您的 GLKViewController 已暂停,并且 GLKView 的 enableSetNeedsDisplay 设置为 1。如果这些已正确设置,则可能是您在后台线程上调用 setNeedsDisplay,并且您的子视图正在触发冲突调用在主线程上。确保对 setNeedsDisplay 的所有调用都是从主线程调用的。一种简单的验证方法是在每个调用旁边放置一个打印语句。
[self.view setNeedsDisplay];
printf("%s\n",dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
另一种方法是将 enableSetNeedsDisplay 设置为零,然后直接调用 [self.view display]。当视图出现和框架发生变化时,您可能必须在这里和那里添加几个显示调用,但它最终会给您更多的控制权。如果它不能完全解决问题,它至少可以更轻松地跟踪堆栈跟踪,因为所有绘制调用都将源自您对显示的调用之一。
Apple 表示异常表示某些后台滥用,并强烈建议进入后台的应用暂停或停止使用 OpenGL ES。
Apple Documentation for Implementing a Multitasking-Aware OpenGL ES App
我的应用程序随机崩溃。最终我发现当我添加 UIVIew 元素并修改它们的中心位置时会发生崩溃。 IPad Air 2 上没有发生崩溃,但 IPad Air 上的情况是一致的 - 当 UIViews 打开时,会发生崩溃,当视图被移除时崩溃会消失。崩溃与以下堆栈异步发生:
#0 0x0000000190bf1f28 in gpus_ReturnGuiltyForHardwareRestart ()
#1 0x0000000190bf2ec4 in gpusSubmitDataBuffers ()
#2 0x0000000189d56254 in gliPresentViewES_Exec ()
#3 0x0000000189d5616c in gliPresentViewES ()
#4 0x0000000189d63cbc in -[EAGLContext presentRenderbuffer:] ()
#5 0x0000000101ff8078 in EAGLContext_presentRenderbuffer(EAGLContext*, objc_selector*, unsigned long) ()
#6 0x00000001877dc638 in -[GLKView _display:] ()
#7 0x000000018b55eeb8 in CA::Layer::display() ()
#8 0x000000018b5413a0 in CA::Layer::display_if_needed(CA::Transaction*) ()
#9 0x000000018b54108c in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#10 0x000000018b54071c in CA::Context::commit_transaction(CA::Transaction*) ()
#11 0x000000018b540470 in CA::Transaction::commit() ()
#12 0x000000018b539c10 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#13 0x000000018666f3f8 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#14 0x000000018666d19c in __CFRunLoopDoObservers ()
#15 0x000000018666d5cc in __CFRunLoopRun ()
#16 0x000000018659d280 in CFRunLoopRunSpecific ()
#17 0x00000001915500cc in GSEventRunModal ()
#18 0x000000018bd8adf8 in UIApplicationMain ()
#19 0x000000010077d36c in main at /Code/splinedr/Splinedr/main.mm:18
#20 0x000000019b7fa8b8 in start ()
我使用调用 [self.view needDisplay]
渲染 OpenGL 并在此之前修改 UIViews。
我该如何处理这个问题?
确保您的 GLKViewController 已暂停,并且 GLKView 的 enableSetNeedsDisplay 设置为 1。如果这些已正确设置,则可能是您在后台线程上调用 setNeedsDisplay,并且您的子视图正在触发冲突调用在主线程上。确保对 setNeedsDisplay 的所有调用都是从主线程调用的。一种简单的验证方法是在每个调用旁边放置一个打印语句。
[self.view setNeedsDisplay];
printf("%s\n",dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
另一种方法是将 enableSetNeedsDisplay 设置为零,然后直接调用 [self.view display]。当视图出现和框架发生变化时,您可能必须在这里和那里添加几个显示调用,但它最终会给您更多的控制权。如果它不能完全解决问题,它至少可以更轻松地跟踪堆栈跟踪,因为所有绘制调用都将源自您对显示的调用之一。
Apple 表示异常表示某些后台滥用,并强烈建议进入后台的应用暂停或停止使用 OpenGL ES。
Apple Documentation for Implementing a Multitasking-Aware OpenGL ES App