今天写程序,在场景转换释放动画缓存的时候,遇到了些问题,记录一下。
我有两个场景A和B,A和B中都要有一个C的Node成员。由于C需要播放动画,因此我在C的构造函数中创建了一个动画缓存存放在了AnimationCache当中,并保存了key,以便在同一个场景中多次调用这个动画不需要每次都要执行Aniamtion->addSpriteFrameWithFile()。
然后我在C的析构当中调用removeAnimation()从动画缓存中释放了该动画。
于是我猜想可能是C的析构是在B的init之后调用的。
得出的结论在这里做个记录:
情况一:
无转场过渡
场景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张图。