cocos2d-x 转场景时构造、init、onEnter、onExit、析构各函数调用顺序

今天写程序,在场景转换释放动画缓存的时候,遇到了些问题,记录一下。

我有两个场景A和B,A和B中都要有一个C的Node成员。由于C需要播放动画,因此我在C的构造函数中创建了一个动画缓存存放在了AnimationCache当中,并保存了key,以便在同一个场景中多次调用这个动画不需要每次都要执行Aniamtion->addSpriteFrameWithFile()

然后我在C的析构当中调用removeAnimation()从动画缓存中释放了该动画。

我在B的init函数中创建了C,当我在B中调用C执行动画时,发生了断言错误,说C通过key在AnimationCache中得到的动画为空。
于是我猜想可能是C的析构是在B的init之后调用的。

其实我一直也没弄清楚转换场景时,场景A、B的各个函数调用顺序,也没遇到过什么大问题,就没有深究。今天为了验证猜想,特意打断点调试了一下。


得出的结论在这里做个记录:

情况一:
无转场过渡
场景A———————————————————————————>场景B
① 构造
② init
③ onExit
④ 析构
⑤ onEnter(B场景绘制到屏幕)


情况二:

有转场过渡
场景A———————————————————————————>场景B
① 构造
② init
③ onEnter(B场景绘制到屏幕)
④ onExit
⑤ 析构


由以上两种情况的调用顺序可以总结一下:

1.无论有无场景过渡,场景B的构造和init都是先被调用

2.场景A的onExit和析构总是在场景B的构造和init之后调用

3.有场景过渡和无场景过渡的区别只是让B场景的onEnter调用顺序发生了改变。

4.无场景过渡的情况下,B场景绘制到屏幕(onEnter)是在场景A内存全部被清理之后才调用的,切换场景时内存压力比较小。
有场景过渡的情况下,B场景绘制到屏幕(onEnter)之后,A场景才从内存中释放,切换时对内存压力较大。

所以,那个问题的猜想是正确的,是我在B场景的init函数中创建了NodeC,C调用构造函数添加了动画缓存。然后A场景调用析构析构自己。当A析构自己时,A的成员C也会被析构,C会调用自己的析构析构自己。在C的析构中又释放了刚刚创建C时添加的动画缓存。这样,相当于没有添加。这里的过程是:

场景A中的成员C被创建时动画缓存中已经存在了该动画缓存。转场景到B时,B的init中又添加了一次改动画缓存,覆盖了原来的动画缓存。

之后A中的成员C被析构,释放了改动画缓存。最后直接导致通过key获取的动画缓存为空。


那么遇到这种情况,应该在哪里添加动画缓存和释放动画缓存呢?
根据上面给出的两种情况图,

我们得出有NodeC成员的图:

无转场过渡
场景A—-—Node C1————————————————————————>场景B——-——Node C2
① 构造
② init
③ 构造
④ onExit
⑤ 析构
⑥ onExit
⑦ 析构
⑧ onEnter(B场景绘制)
⑨ onEnter



发现B场景的成员C2调用onEnter是在C1析构以后进行的,因此应该在C的onEnter中加载动画。

但是有场景过渡时,这样做会断言错误。原因请根据情况一和二推导一下。

问题解决,原因已晓。下次忘了可以看看这3张图。

cocos2d-x 转场景时构造、init、onEnter、onExit、析构各函数调用顺序弄清楚了。以前的困惑解除。

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...