展会信息港展会大全

cocos2dx 中切换场景内存占用过高的处理
来源:互联网   发布日期:2015-09-28 15:39:38   浏览:1880次  

导读:cocos2dx 中切换场景内存占用过高的处理1、运行场景:CCScene *pScene = HelloWorld::scene();pDirector->runWithScene(p...

cocos2dx 中切换场景内存占用过高的处理

1、运行场景:

CCScene *pScene = HelloWorld::scene();

pDirector->runWithScene(pScene);

2、替换场景:

(1)

CCScene *pScene=SceneTestScene::scene();

CCDirector::sharedDirector()->replaceScene(pScene);

(2) CCScene *pScene=SceneTestScene::scene();

CCDirector::sharedDirector()->pushScene(pScene);

(3) CCScene *pScene=SceneTestScene::scene();

CCDirector::sharedDirector()->popScene(pScene);

3具体的代码执行流程

假设scene A是活动场景,现在我们用scene B来pushScene替换A,A和B的生命周期是这样的:

B ---- init();

A ---- onExit();

B ---- onEnter();

B ---- onEnterTransitionDidFinish();

此时popScene,弹出scene B,函数调用如下:

B ---- onExit();

B ---- 析构函数被调用

A ---- onEnter(); (并不会执行sceneA的init函数 ,因为 pushScene的时候会执行sceneA的onExit函数释放一些资源, 当pup的时候,不会执行init函数加载需要的资源,出现为止的错误)

从上面可以看出以下几点,

1. A的析构函数始终未被调用,因此A一直在内存中。

2. 先执行B的init()函数,之后才调用A的onExit()方法,再之后才调用B的onEnter();所以初始化最好应该放在init中来初始化。在上一个场景退出之前初始化好后一个场景需要的资源。(内存占用过高出现在这里)

同样的,我们再来看一下replaceScene切换场景,scene的生命周期

假设scene A是活动场景,现在我们用scene B来replaceScene替换A,A和B的生命周期是这样的:

B ---- init();

A ---- onExit();

A ---- 析构函数被调用

B ---- onEnter();

B ---- onEnterTransitionDidFinish();

此时B replace A回来的调用跟上面一样,如下:

A ---- init();

B ---- onExit();

B ---- 析构函数调用

A ---- onEnter();

4具体的引擎的执行代码, 查看对象的生命周期。见下面的链接 http://blog.csdn.net/tonny_guan/article/details/28121973

-----------------华丽的分割线---------------- 当使用replaceScene切换场景的时候,在游戏所占有的内存是当前内存峰值时多少哪,很可怕的 时当前场景的内存值,加上下一个场景的资源所占用的内存值。 原因。。。。 在每个场景里面会有一个init函数,一个onEnterTransitionDidFinish函数,一个Onexit函数,init实现一些初始化工作,onEnterTransitionDidFinish在init之后执行,Onexit在场景退出时回收init时分配的资源。在调试时发现一个很有趣的现象,那就是从场景一切换到场景二时,在切换的一瞬间会内存会非常高,但是过了一段时间后,内存会回到一个平稳的状态,譬如切换时内存会达到80M,切换过后内存会降到50M。分析原因,怀疑是上一个场景的内存还没有释放,然后这一个场景的内存已经分配,所以两个叠加在一起,就比较高了。所以我便在第一个场景的Onexit函数中加一个断点,在第二个场景的init和onEnterTransitionDidFinish函数中各加一个断点,然后运行程序,发现程序先到第二个场景的init中,然后再回到第一个场景的Onexit中,最后才到第二个场景的onEnterTransitionDidFinish中。我才恍然大悟,原来在场景切换时,不是马上会执行第一个场景的Onexit函数,而是先到第二个场景的init中加载资源,然后回到第一个场景中释放资源,最后才是到onEnterTransitionDidFinish中。 内存中的峰值很惊人。

方案一, 将必要的资源放在onEnter 中处理,其他的资源 放在onEnterTransitionDidFinish处理。 方案二 , 给场景切换添加一个过度场景,现在主流的rpg ,或者横版格斗的游戏都已经这样处理。 因为资源量比较大,这样处理高效并且安全。

--总结

1. 切换全屏场景的时候最好使用replaceScene而不是pushScene。

因为pushScene并不会销毁前一个scene,仅仅是将后一个scene按照堆栈的方式加入到前一个scene的上面。如果自身代码中内存管理写的不好的,利用pushScene很难发现该方面的问题,一旦崩溃定位都很难定位。replaceScene可以及早的将隐含的问题给暴露出来。

2. 尽量不要在onEnter里面初始化精灵Sprite

这个就和上一条有点关系了,如果使用了pushScene,那么再popScene的时候是不会调用前一个场景的init方法的(上一个界面的资源有的已经释放,这时出现未知的错误),所以有同学就喜欢把一些初始化放在onEnter里面,具体为什么不好,我们来看一下不同切换场景的时候,每个Scene的生命周期就知道了。

赞助本站

人工智能实验室
AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港