在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. URL参数转换对象

    var parseQueryString = function (url) { var reg_url = /^[^\?]+\?([\w\W]+)$/, reg_para = /([^&=]+ ...

  2. 【Nodejs】使用put方式向后端查询数据并在页面显示

    前端代码: <!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Ty ...

  3. android 实现qq聊天对话界面效果

    效果图: chatting_item_from.xml <?xml version="1.0" encoding="UTF-8"?><Line ...

  4. iOS SEL类型和创建

    SEL selAction =NSSelectorFromString([actionArrayobjectAtIndex:indexArray]); [item addTarget:self act ...

  5. NDK 编译armebai-v7a的非4字节对齐crash Fatal signal 7 (SIGSEGV) 错误解决

    一直都是编译armabi的.没有不论什么问题,这个架构是软件模拟浮点运算的. 后来看到NDK文档上说armabi-v7a是针对有硬件处理浮点计算的arm cpu的. 于是就改动配置编译armebai- ...

  6. C++ union使用注意

    union在我们敲代码的时候的使用概率远远小于struct.所以我们常常不太关心她.就知道他是使用内存复用技术.同一个时刻,他仅仅能存在一个成员的值. C中,我们在union中能够包括struct的, ...

  7. Codeforces Round #228 (Div. 1) C 贪心

    嘎嘎,今天被一些事耽误了,可是还是A了几个题目,这道题还不错 题目链接: 题意:两个人玩游戏,有N堆纸牌,纸牌上有数字,A每次仅仅能取N堆中的 当中一个的顶部的 纸牌,B仅仅能取N堆中的当中一个底部 ...

  8. margin和padding的学习

    你在学习margin和padding的时候是不是懵了--什么他娘的内边距,什么他娘的外边距.呵呵呵,刚開始我也有点不理解,后来通过查资料学习总算弄明确了,如今我来谈一下自己对margin和paddin ...

  9. cydia源

    http://apt.91.com http://apt.178.com Flex 2的官方安装源是 getdelta.co

  10. logging日志管理--将日志打印在屏幕上

    # -*- coding: cp936 -*- # test.py #http://blog.chinaunix.net/uid-27571599-id-3492860.html #logging日志 ...