按Home键切换到后台后会触发libGPUSupportMercury.dylib: gpus_ReturnNotPermittedKillClient导致crash

本文探讨了iOS应用在真机调试时遇到的问题:当从后台返回时App崩溃或僵死的情况。问题根源在于AppDelegate中对CCDirector的处理不当。文章提供了具体的代码修改方案,以确保App在后台不会调用OpenGL,避免崩溃。

苹果解读:

http://developer.apple.com/library/ios/#qa/qa1766/_index.html


转自:http://www.eoeandroid.com/thread-251598-1-1.html


好像有很多朋友都碰到过这个问题,即在真机调试时,按hone键返回桌面,再回到app时,app会crash或僵死。同时xcode停留在:
libGPUSupportMercury.dylib`gpus_ReturnNotPermittedKillClient:
0x372fa094: trap
0x372fa096: nop


原因在于AppDelegate.cpp里

void AppDelegate::applicationDidEnterBackground()

{

    CCDirector::sharedDirector()->pause();


}

void AppDelegate::applicationWillEnterForeground()

{

    CCDirector::sharedDirector()->resume();


}

director在app切换至后台时若被pause,它其实并没有真正暂停,而是仍保持着每秒4帧的绘制速率。但在app处于后台时,ios是不允许app调opengl的。这个原因引发了上述问题。

解决方法是:
void AppDelegate::applicationDidEnterBackground()
{
    CCDirector::sharedDirector()->stopAnimation();
}
void AppDelegate::applicationWillEnterForeground()
{
    CCDirector::sharedDirector()->startAnimation();
}

stopAnimation()才让director真正暂停下来。



另:播放视频时按home键crash问题:
http://blog.k-res.net/archives/1193.html


在iOS应用开发中,崩溃问题通常与内存管理或线程处理相关。您提到的崩溃堆栈信息中涉及 `libdispatch.dylib` 和 `HDClient logout`,表明问题可能与GCD(Grand Central Dispatch)机制或HealthKit框架中的线程管理有关。 ### 内存管理相关问题分析 崩溃发生在 `__dispatch_lane_class_dispose` 函数中,这是libdispatch(GCD)的一部分,负责调度和管理异步任务。该函数通常在释放某个调度队列(`dispatch_queue_t`)时被调用。如果在此过程中出现内存访问异常,可能的原因包括: - **过度释放(Over-release)**:某个对象被释放了多次,导致内存访问越界。 - **未初始化的指针**:使用了一个未正确初始化的指针。 - **多线程竞争条件**:多个线程同时访问共享资源,未进行适当的同步控制。 ### 线程处理相关问题分析 `HDClient logout` 表明崩溃可能与HealthKit的客户端注销过程有关。HealthKit框架通常在后台线程中执行操作,若在主线程中调用同步方法或未能正确处理异步回调,可能导致死锁或线程冲突。 - **主线程阻塞**:如果在主线程中调用了同步的HealthKit方法,可能导致UI冻结,甚至触发watchdog机制导致崩溃。 - **异步回调处理不当**:HealthKit的许多API需要异步调用,若未能正确处理completion handler,可能导致内存泄漏或线程安全问题。 ### 解决方案与调试建议 1. **启用 Zombie Objects**:通过启用NSZombieEnabled,可以检测到已释放的对象是否被再次访问,有助于定位过度释放问题。 2. **使用 Instruments 工具**:通过Xcode的Instruments工具,特别是Leaks和Allocations模板,可以检测内存泄漏和异常释放行为。 3. **检查线程安全**:确保所有对共享资源的访问都使用锁机制(如`@synchronized`或`NSLock`)进行保护。 4. **避免主线程阻塞**:将HealthKit等耗时操作移至后台线程,并使用completion handler进行结果回调。 5. **符号化崩溃日志**:使用Xcode的Organizer功能对崩溃日志进行符号化,以获取更详细的调用栈信息。 ```swift // 示例:HealthKit注销操作应确保在后台线程执行 DispatchQueue.global(qos: .utility).async { do { try healthStore.revokeAuthorization(for: HKObjectType.quantityType(forIdentifier: .heartRate)!) DispatchQueue.main.async { // 更新UI } } catch { print("Revoke authorization failed: $error)") } } ``` 通过上述方法,可以有效分析和定位与内存管理和线程处理相关的iOS崩溃问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值