在cocos2dx 3.3中下面myScene在切出时会存在概率性崩溃(代码作了最大程度简化,仅为说明问题):

class CmyLayer:public Layer{

public:

  CmyLayer(){

    m_sprite=NULL;

    m_renderTex=NULL;

  }

  virtual~CmyLayer(){

  }

  bool init(){

    m_sprite=Sprite::create("a.png");

    this->addChild(m_sprite);

    m_renderTex=RenderTexture::create(w,h);

    this->addChild(m_renderTex);

    

    return true;

  }

  void udpate(float dt){

    m_renderTex->begin();

    m_sprite->visit();

    m_renderTex->end();  

  }

private:

  RenderTexture* m_renderTex;

  Sprite* m_sprite;

};

class CmyScene:public Scene{

public:

  CmyScene(){

  }

  virtual~CmyScene(){

  }

  bool init(){

    CmyLayer*myLayer=new CmyLayer();

    myLayer->autorelease();

    myLayer->init();

    addChild(myLayer);

    return true;

  }

};

在myScene场景切出时概率性地崩溃在两个位置:

(1)RenderTexture的onBegin函数里,在RenderTexture的实现中onBegin是作为customCommand发出去的。

(2)崩溃在RenderTexture的GroupCommand里。

其中第一个崩溃位置出现频率占大多数。

崩溃在command里是最坑爹的,因为其执行是异步的,所以当崩溃时很难调查对象在发出此command时的当时状态,甚至连发出command的对象是谁都很难知道!数据/状态一致性问题和debug困难是我讨厌command机制的主要原因。

先停止吐槽,猜测崩溃原因,认为很可能是在场景切出时由于m_renderTex随myLayer一起销毁,但m_renderTex发出的customCommand已加入到command队列且尚未执行,这样当等到此customCommand执行时,它会调用m_renderTex的onBegin函数,但m_renderTex已销毁,所以产生不可预料的结果。

为了避免“对象已销毁但其customCommand已发出却尚未执行”而导致的“调用对象不存在”的情况出现,我尝试采取了下面两个措施:

1,在场景切出时尽早停止CmyLayer::update。(因为崩溃的customCommand是在CmyLayer::update的m_renderTex->begin()中发出的)

2,在场景切出时推迟销毁m_renderTex。

具体地,CmyLayer代码改成:

class CmyLayer:public Layer{

public:

  CmyLayer(){

    m_sprite=NULL;

    m_renderTex=NULL;

  }

  virtual~CmyLayer(){

    if(m_renderTex)m_renderTex->autorelease();//add, inorder to achieve delay release, use autorelease instead of release

    if(m_sprite)m_sprite->autorelease();//add, inorder to achieve delay release, use autorelease instead of release

  }

  bool init(){

    m_sprite=Sprite::create("a.png");

    this->addChild(m_sprite);

    m_sprite->retain();//add

    m_renderTex=RenderTexture::create(w,h);

    this->addChild(m_renderTex);

    m_renderTex->retain();//add

    

    return true;

  }

  void udpate(float dt){

    m_renderTex->begin();

    m_sprite->visit();

    m_renderTex->end();  

  }

  void onExit(){

   CCLayer::onExit();

this->unscheduleUpdate();//add, stop update as soon as possible

}

private:

  RenderTexture* m_renderTex;

  Sprite* m_sprite;

};

我不知道这两处改动是否都是必须的,由于是概率性崩溃,验证和重现比较耗时,所以在没有更清晰的分析之前暂时两处改动都保留。如此改之后目前为止还没有再发生崩溃。但这种修补显然是不自然的,不知道有没有更好的办法。

cocos2dx 3.3 场景切出时RenderTexture crash的更多相关文章

  1. 微信小程序自动化jest模拟场景/切出/切入

    await miniProgram.evaluate(() => getApp().clickBanner({ path: "pages/game/home/home", q ...

  2. 关于png、jpg、gif切图时的使用感悟

    关于png.jpg.gif切图时的使用感悟 曾经切图时都是一股脑所有图全切成jpg格式,最近突然心血来潮简单的研究了下其他图片格式的具体属性,才突然发现走了不少弯路,并没有做到使图片用最小体积展现出最 ...

  3. Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题

    最近项目中遇到一个问题,用户第一次安装应用在系统的安装器安装完成界面有“完成”和“打开”两个按钮. 当用户点击“打开”按钮进入用户注册页面进行手机号验证码发送和验证码输入等操作界面,若此时用户点击Ho ...

  4. cocos2dx中的场景和使用方法

    1.一个游戏中有且只有一个导演,但是至少有一个场景 2.场景是游戏元素节点数的根节点,也可以理解为该场景下的渲染树的根节点 3.场景是一个容器,包含了该场景下的所有游戏元素,比如层,精灵 4.场景是导 ...

  5. Android 软键盘弹出时把原来布局顶上去的解决方法

    键盘弹出时,会将布局底部的导航条顶上去. 解决办法: 在mainfest.xml中,在和导航栏相关的activity中加: <activity            android:name=& ...

  6. 当SD卡拔出时,返回首页,栈中的activity都要清除,只留下首页的activity

    目标:当SD卡拔出时,返回首页,栈中的activity都要清楚,只留下首页的activity 我在清单中注册了一个静态广播: <receiver android:name="com.p ...

  7. svn 切出指定版本、更改版本名称、删除分支

    1,切出指定版本 svn copy svn://192.168.1.52/help/branches/help_forShop_140307 -r 170 svn://192.168.1.52/hel ...

  8. 切服务器时请注意robots.txt文件

    最近两天切服务器时又出现测试机器忘记改robots.txt文件的情况,以后就用个二级域名做测试,测试的机器也不对robots.txt作限制.

  9. 学习笔记:只有一套app设计稿(5s尺寸)切出4和4s尺寸以及安卓系统主流尺寸的图

    如何在只有一套app设计稿(5s尺寸)切出4和4s尺寸以及安卓系统主流尺寸的图 转自:http://www.zhihu.com/question/23255417   版权归原作者所有 目前ios手机 ...

随机推荐

  1. Linux之nohup命令:实现退出终端后程序继续后台运行

    转自:http://tech.ccidnet.com/art/302/20070618/1115599_1.html 简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后 ...

  2. [android错误] requires API level *

    Call requires API level (current min ): android.content.res.Resources#getBoolean 参考文档: http://stacko ...

  3. 【转】允许远程用户登录访问mysql的方法

    需要手动增加可以远程访问数据库的用户. 方法一.本地登入mysql,更改 "mysql" 数据库里的 "user" 表里的 "host" 项 ...

  4. STL - 容器 - UnorderedSet(一)

    一些简单操作 UnorderedSetTest.cpp #include <unordered_set> #include <numeric> #include ". ...

  5. JavaScript debugger 语句

    实例 开启 debugger ,代码在执行到第三行前终止. var x = 15 * 5; debugger; document.getElementbyId("demo").in ...

  6. java 打包war包

    jar -cvf  news.war news war包放在Tomcat webApp中可以自动解压.

  7. Oracle的PLSQL别名中文出现乱码解决方法

     乱码之乱,乱在心里.行而上,眼迷茫! 01.查询oracle服务端默认语言 select * from nls_database_parameters NLS_LANGUAGE AMERICAN   ...

  8. Android仿掌上英雄联盟首页,实现折叠效果

    概述 仿掌上英雄联盟首页的demo 详细 代码下载:http://www.demodashi.com/demo/10695.html 首页大概分为几个部分 状态栏 标题栏 轮播图 切换的Tab 资讯列 ...

  9. Spring MVC Beginner’s Guide勘误表

    - 17 submitted: last submission 09 Dec 2016 Page number: 213 Qauntity should be: Quantity Page numbe ...

  10. HDUOJ--畅通工程

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...