COCOS2D 释放资源的最佳时机
有场景A跟场景B,
场景A是当前场景,场景B是将要替换的新场景。
那么A场景的资源释放最佳时机是在什么时候呢?
这是释放资源的代码(注意要按这个顺序释放):
|
1
2
3
4
|
CCAnimationCache::purgeSharedAnimationCache();SpriteFrameCache::getInstance()->removeUnusedSpriteFrame();CCTextureCache::getInstance()->removeUnusedTextures();CCTextureCache::getInstance()->getCachedTextureInfo(); |
1.
最开始我想到的,应该是在场景A的onExit里释放,试验了下,资源并没有被释放,说明当前纹理仍然在
被引用,即场景A的子节点并未remove。
后来查了下,发现每个场景的资源释放都是在一个叫dealloc的方法里,而这个方法是在onExit之后执行的。
也就是说在onExit里释放资源是不合适的做法。
2.
我突然想起来,每个类不都有个析构函数么?析构函数是在该类的对象被delete时调用的,
只要在A场景的析构函数里释放不就可以了?试验了下,发现也没效果,
仔细想想,我创建场景用的方法是Cocos2DX推荐的默认方法,即场景类继承一个Layer,
然后再createScene里创建一个Scene,再把当前类添加到Scene里。替换场景后,
该Layer被释放时,场景中的其他资源并不一定被释放,所以此方法也是行不通的。
3.
竟然场景真正remove子节点是在dealloc方法里,那么在dealloc里释放资源不就好?
可惜的是我根本就找不到有这个方法。于是放弃了。
后来百度了下场景的调用顺序规则:
|
1
2
3
4
5
6
7
|
replaceScene : SceneBinit : SceneBonExitTransitionDidStart : SceneAonExit : SceneAdealloc : SceneAonEnter : SceneBonEnterTransitionDidFinish : SceneB |
由此可看出,B场景的onEnter函数在A场景的dealloc之后执行。
而且
那么只要在B场景的onEnter里释放A场景的资源就可以。
试验了下,资源的确被释放了。
而且,释放资源是在B场景的init之后执行,这样的好处就是,假设场景B中用到场景A中的某些资源,
这些资源就不会被释放再加载,造成不必要的内存高峰。
4.
问题到此结束了吗?我也以为结束了,然后又发现新问题。
一旦我给场景过渡加上效果,以上方法就不灵验了,释放失败。
|
1
|
Director::getInstance()->replaceScene(CCTransitionFade::create(0.5f, SceneB::createScene())); |
然后调试跟踪下执行顺序,发现问题所在了。
当有过渡效果存在的时候,执行顺序变成这样:
|
1
2
3
4
5
6
|
replaceScene : SceneBinit : SceneBonExitTransitionDidStart : SceneAonEnter : SceneBonExit : SceneAonEnterTransitionDidFinish : SceneB |
没错,场景A并不会立刻结束,而是等到动画效果完毕后才结束。
但是我发现不管有没有使用过渡动画,最后执行的总是onEnterTransitionDidFinish,
那么我们只要将资源释放放在这里就行了。
经过试验,发现又失败了。。。
为啥,因为虽然dealloc方法是在onExit之后执行,但并不是紧追其后,也就是说,
有可能在onEnterTransitionDidFinish 之前,也有可能在其后,因此我们直接在
onEnterTransitionDidFinish 里释放资源并不一定可行。那该怎么解决?
这里我使用了延时释放的方法,在onEnterTransitionDidFinish 执行后过一段时间,
再调用释放资源的方法,这样就可以确保资源被释放。
|
1
|
scheduleOnce(CC_SCHEDULE_SELECTOR(SceneB::release), 2.0f); |
5.
以上方法的确是可以将资源释放掉,但是不是我们所要的”最佳时机”呢?
仔细观察,B场景的init是在A场景的释放之前的,也就是说,在B场景诞生,A场景彻底释放
的短时间内,会存在A,B场景的所有资源共存的现在。这个时候内存达到巅峰。如果A场景
跟B场景的资源所占内存都非常大的时候,或许会造成崩溃。
那么我们应该如何解决?
目前我的解决方法就是在场景过渡的时候增加一个过渡场景,也就是Loading场景,Loading场景
本身所需的资源并不多,在A场景资源释放完毕后,再开启B场景的资源加载。
COCOS2D 释放资源的最佳时机的更多相关文章
- cocos2d源码剖析
1. TextureAtlas http://www.cocoachina.com/bbs/read.php?tid-311439-keyword-TextureAtlas.html 2. Label ...
- cocos2D(三)---- 第一cocos2d的程序代码分析
在第一讲中已经新建了第一个cocos2d程序,执行效果例如以下: 在这讲中我们来分析下里面的代码,了解cocos2d的工作原理,看看屏幕上的这个"Hello World"是怎样显示 ...
- 三、第一个cocos2d程序的代码分析
http://blog.csdn.net/q199109106q/article/details/8591706 在第一讲中已经新建了第一个cocos2d程序,运行效果如下: 在这讲中我们来分析下里面 ...
- 小尝试一下 cocos2d
好奇 cocos2d 到底是怎样一个框架,正好有个项目需要一个游戏框架,所以稍微了解了一下.小结一下了解到的情况. 基本概念 首先呢,因为 cocos2d 是基于 pyglet 做的,你完全可以直接用 ...
- 采用cocos2d-x lua 制作数字滚动效果样例
require "Cocos2d"require "Cocos2dConstants"local testscene = class("testsce ...
- Cocos2d 利用继承Draw方法制作可显示三维数据(宠物三维等)的三角形显示面板
很久没有写博客了,这段时间比较忙,又是搬家又是做自己的项目,还有太多琐碎的事情缠身,好不容易抽出时间把最近自己做的一些简单例子记录一下. 在我的项目中,我需要一个显示面板来显示游戏中的一个三维数据,例 ...
- iPhone开发与cocos2d 经验谈
转CSDN jilongliang : 首先,对于一个完全没有mac开发经验,甚至从没摸过苹果系统的开发人员来说,首先就是要熟悉apple的那一套开发框架(含开发环境IDE.开发框架uikit,还有开 ...
- using 释放资源
我们知道使用C#程序访问数据库资源需要几个步骤:创建连接,打开连接,访问数据库,关闭连接,基本架构如下: SqlConnection conn = new SqlConnection(connStri ...
- cocos2d学习记录
视频 - http://www.manew.com/forum-105-3.html一个论坛帖 - http://www.zhihu.com/question/21114802官网 - http:// ...
随机推荐
- Jenkins的FTP上传插件Publish Over FTP Plugin设置支持中文路径
[系统管理]->[系统设置]->[Publish over FTP]->[Control encoding]->输入[GB2312]或者[UTF-8]
- JeeSite环境搭建及运行和打包(master20161117)
涉及的软件: 1.phpStudy(主要用MySql) 2.maven3(用于依赖包,下面我将上传已经下载好所有依赖包的版本,保证运行正常) 具体操作: 0.前言 由于GitHub上的Release版 ...
- xcoj 1208 矩阵
赛场上一开始以为是递推,交了一发希望以为能卡着线过(毕竟是O(5N)的),结果WA了. 又以为是dp,最后半小时尝试各种YY...各种WA 实际上取每次transfer中最大的概率然后递推是不对的.. ...
- CVE-2014-0050: Exploit with Boundaries, Loops without Boundaries、Apache Commons FileUpload and Apache Tomcat DoS
catalog . Description . Analysis . POC . Solution 1. Description MultipartStream.java in Apache Comm ...
- css居中那点事儿
css居中那点事儿 在css中对元素进行水平居中是非常简单的,然而使元素垂直居中就不是一件简单的事情了,多年以来,垂直居中已经成为了CSS领域的圣杯,因为它是极其常见的需求,但是在实践中却不是一件简单 ...
- 9.19 JS数组
数组:相同类型数据的集合强类型语言:1数组里面只能存放相同数据类型的数据 2定义数组的时候需要制定一个长度(可以存放的元素数量) 3内存空间连续集合:1.可以存放任意类型的数据 ...
- CentOS7安装Ambari
环境: CentOS7安装两个节点:master.slave1.并配置ssh无密码登录. 步骤: 获取 Ambari 的公共库文件(public repository): wget http://pu ...
- CentOS7搭建hadoop2.6.4+HBase1.1.6
环境: CentOS7 hadoop2.6.4两个节点:master.slave1 HBase1.1.6 过程: hadoop安装目录:/usr/hadoop-2.6.4 master节点,hadoo ...
- WinForm------如何将GridControl数据导出到Excel
转载: http://www.cnblogs.com/xiaofengfeng/archive/2011/11/22/2258906.html 代码: SaveFileDialog saveFileD ...
- llinux 查看自己的公网ip
如何在LINUX服务器下查看公网IP地址,可以使用下面的方法: [root@web ~]#curl http://members.3322.org/dyndns/getip [root@web ~]# ...