Cocos2d on iOS: EXC_BAD_ACCESS in CCGraphicsBufferGLUnsynchronized when leaving app after ad

Cocos2d on iOS: EXC_BAD_ACCESS in CCGraphicsBufferGLUnsynchronized when leaving app after ad

我已经将 UnityAds 的 SKD 集成到我的游戏中以显示全屏插屏视频广告。

视频播放完毕后,广告框架会向 AppStore 提供 link。当我select 这个link,AppStore 就打开了。我的应用程序此时崩溃,在 CCGraphicsBufferGLUnsynchronized 中抛出 EXC_BAD_ACCESS。

启动我的应用程序时,UnityAds SDK 初始化如下:

[[UnityAds sharedInstance] startWithGameId:UNITYADS_MYAPP_ID
                                        andViewController:[CCDirector sharedDirector]
                ];

如您所见,我将 [CCDirector sharedDirector] 作为视图控制器传递。我提到这个,因为这可能是问题的一部分?

稍后我从 Cocos2D 场景中调用 UnityAds SDK,如下所示:

-(void)showFullscreenAd {
    //  Stop Cocos2D rendering
    [[CCDirector sharedDirector] pause];
    [[CCDirector sharedDirector] stopAnimation];

    //  Is an ad available?
    if ([[UnityAds sharedInstance] canShowAds]) {
        //  Display the ad
        [[UnityAds sharedInstance] setZone:@"rewardedVideoZone"];
        [[UnityAds sharedInstance] show];
    }
}

如您所见,我在显示添加之前停止了 Cocos2D 渲染。

当我 select 添加 AppStore link 时,我的应用程序崩溃了。 这是崩溃后 Xcode 指向我的代码(在 class CCGraphicsBufferGLUnsynchronized 中)

-(void)prepare
{
    _count = 0;

    GLenum target = (GLenum)_type;
    glBindBuffer(_type, _buffer);
 ==>    _ptr = _mapBufferRange(target, 0, (GLsizei)(_capacity*_elementSize), BUFFER_ACCESS_WRITE);
    glBindBuffer(target, 0);
    CC_CHECK_GL_ERROR_DEBUG();
}

有人可以为我指出正确的调试方向吗?

我 运行 我的应用在 iPad 和 iPhone iOS 8.1.3

好的,我自己找到了解决办法。似乎发生崩溃是因为应用程序在后台并且渲染继续进行。所以我所要做的就是确保在应用程序移动到后台后不会恢复渲染。

我现在是这样做的:

//  Added a flag to control resuming of rendering
@property (readwrite) bool resumeRendering;


[...]


-(void)showFullscreenAd {
    //  Stop Cocos2D rendering
    [[CCDirector sharedDirector] pause];
    [[CCDirector sharedDirector] stopAnimation];

    // Set to resume redering by default
     _resumeRendering = YES;

    //  Is an ad available?
    if ([[UnityAds sharedInstance] canShowAds]) {
        //  Display the ad
        [[UnityAds sharedInstance] setZone:@"rewardedVideoZone"];
        [[UnityAds sharedInstance] show];
    }
}


[...]


#pragma mark - UnityAdsDelegate

//  This method is called when the interstitial ad is discarded
//  check if rendering should be resumed
-(void)unityAdsDidHide {
    if ( _resumeRendering ) {
        [[CCDirector sharedDirector] resume];
        [[CCDirector sharedDirector] startAnimation];
    }

    // do anything else here
    // In my case I transfer to the next scene
    [...]
}

-(void)unityAdsWillLeaveApplication {
   // Will leave application. Make sure rendering is not resumed anymore
    _resumeRendering = NO;
}

现在当用户点击广告中的 AppStore link 时,unityAdsWillLeaveApplication 方法将被调用,我可以将 resumeRendering 标记为 false。

希望这对其他遇到同样问题的人有所帮助。