oc中广告sdk的原生oc的回调函数调用cocos没问题,而cocos调用oc,oc当场调回cocos就有问题

cocos调用ios中广告平台的的oc代码,比如显示广告,很正常。当广告播放完毕,用户关闭广告,那么广告相关的函数会被回调原生oc代码,oc代码再调用cocos函数function1,funtion1会包含一些界面处理比如隐藏loading。

这些都没问题。

但是如果某个广告sdk的oc代码准备显示广告时,发现之前加载失败,那么此时不会调用广告sdk的方法,而是直接调用cocos方法funtion1,而cocos的function1会隐藏loading,但这个情况,对于admob或穿山甲会有问题,function1中隐藏loading的语句失效,其它语句正常。

也就是说oc中广告sdk的原生oc的回调函数调用cocos没问题,而cocos调用oc,oc当场调回cocos就有问题。

试了定时器,都没解决,哪位有碰到过吗?

问了ai,给了多个解决方法,有一个方法有效
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
JsbBridge* m = [JsbBridge sharedInstance];
[m sendToScript:@“iosAdmobCallback” arg1:@“2”];
});

1赞

你这个场景我遇到过,本质是广告 SDK 在"加载失败直接回调"和"播放完毕正常回调"两条路径上,回到 Cocos 时的引擎状态不一样。

正常播放完毕的回调,Cocos 侧的渲染循环和节点树是稳定的,所以 function1 里隐藏 loading 没问题。但加载失败那条路径,广告 SDK 可能在 Cocos 还没完全准备好(比如场景刚切换、节点还没挂载完)的时候就触发了回调,这时候 function1 里涉及 UI 节点操作的语句就会失效,其他非 UI 的语句正常执行——跟你描述的现象一致。

你用的 dispatch_after 0.5 秒是有效的,因为它给了 Cocos 引擎一个完整的帧周期去稳定状态。不过 0.5 秒用户可能会看到 loading 多停留半秒,体验上稍有感知。如果想更精细,可以试试两个方向:

1.把延迟缩短到 0.1–0.2 秒,大部分情况下一个帧周期就够了,不用等太久。
2.在 Cocos 侧加一个状态标记,比如 isLoadingScene,OC 回调时先检查这个标记,如果 Cocos 还没准备好就把回调缓存起来,等 Cocos 侧主动来取。这样既不需要延迟,也不会丢回调。

另外 AdMob 和穿山甲都有这个问题,说明不是某一家 SDK 的 bug,而是 Cocos 和原生 OC 之间回调时机不一致的通用问题。不同 SDK 的失败回调线程策略不一样,统一用主线程 + 短延迟的方式处理会比较稳。