转:https://blog.csdn.net/winthinking/article/details/50708114
关于资源释放的问题,首先要了解cocos2d-x 场景切换过程,这样才知道什么时候释放才是合适的。有A,B两个场景,假如从A切换到B,那么顺序如下:
切换时无特效,即CCDirector::sharedDirector()->replaceScene(B):
1.B->init()
2.A->onExitTransitionStart()
3.A->onExit()
4.B->onEnter()
5.B->onEnterTransitionFinish()
到此,B的场景创建完毕。再看有特效时,即CCDirector::sharedDirector()>replaceScene(CCTransitionJumpZoom::create(1.0f,B));
1.B->init()
2.A->onExitTransitionStart()
3.B->onEnter()
4.A->onExit()
5.B->onEnterTransitionFinish()
看到上面的区别了吧,2,3步骤置换了下。
下面切换到正题,我们知道游戏中主要吃掉内存的是纹理,考虑到渲染浪费时间的问题,所以用到的小图片尽量用工具TexturePacker生成大图片,由于TexturePacker生成的图片尺寸是2指数倍如:256*256。所以要规划下,哪些图片要生成在其中,避免生成的尺寸过大,徒劳增加包体大小。
项目中可能用到很多缓存类:如CCSpriteFrame,CCAnimationCache,CCTextureCache等,大多数情况下,最终占用资源的是CCTextureCache,场景中 所有用到的图片最终都会生成在此缓存中。当多种缓存类存在情况下,删除是有先后顺序的,如果直接释放CCTextureCache,那么将会其他描述缓存找不到资源而引发程序的崩溃。在我的项目中用到了cocostudio做的动画,使用到了cocos2d-x引擎下的extensions下的控件。所以我的释放顺序是:
1.GUIReader::shareReader()->purge();
控件描述文件json解析类,即GUIReader,GUIReader对象创建时,没有引用计数的内存管理模式,所以手动调用purge(),销毁对象
2.CCArmatureDataManager::sharedArmatureDataManager()->purge();
骨骼动画数据缓存清除,追到purge()内查看:
CCSpriteFrameCacheHelper::purge(); 对s_SpriteFrameCacheHelper对象的安全销毁
CCDataReaderHelper::purge();对s_arrConfigFileList(实际上是vector)进行clear 和 s_DataReaderHelper 销毁
CC_SAFE_RELEASE_NULL(s_sharedArmatureDataManager); 自身对象数据销毁
3.CCAnimationCache::sharedAnimationCache()->purgeSharedAnimationCache();
对动画缓存对象安全释放,其中最主要释放的是CCDictionary成员
4.CCSpriteFrameCache::sharedSpriteFrameCache()->purgeSharedSpriteFrameCache();释放帧图片缓存
5.CCTextureCache::sharedTextureCache()->purgeSharedTextureCache(); 最后释放纹理
以上就是资源释放顺序,那么这段程序放在A->B场景切换的哪个函数中呢?我的选择是在B的构造函数、init()其中的一处,当然这段程序一定要放在其他资源创建之前(如按钮的创建等)。如果A,B场景中有共用资源,资源分的不是那么清怎么办呢。。。。也不怕,在这段程序之后再次加载,由于加载资源是一个读文件的过程,比较费时,可以选择异步加载 或是 根据场景用到资源顺序,在每隔一段时间加载一部分资源。