博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx3.0 removeFromParent和removeAllChildren含义
阅读量:4650 次
发布时间:2019-06-09

本文共 4600 字,大约阅读时间需要 15 分钟。

顾名思义,removeFromParent就是把自己从父亲那里移除,removeAllChildren就是移除自己所有的孩子,这些方法的具体实现都在基类Node里面,通过查看代码也很容易看到怎么实现的。

现在主要看下他们两个的调用顺序

 示例代码如下:

比如自定义一个类Layer,

#ifndef _MAINMENU_H1_#define _MAINMENU_H1_#include "cocos2d.h"using namespace cocos2d;using namespace std;class Layer1 : public Layer{public: Layer1(); virtual ~Layer1(); bool init(); virtual bool onTouchBegan(Touch *pTouch, Event *pEvent); virtual void onTouchMoved(Touch *pTouch, Event *pEvent); virtual void onTouchEnded(Touch *pTouch, Event *pEvent); virtual void onTouchCancelled(Touch *pTouch, Event *pEvent); string haha; CREATE_FUNC(Layer1); }; #endif
#include "Layer1.h"Layer1::Layer1(){                }Layer1::~Layer1(){            printf("析构函数");    }bool Layer1::init(){  // this->setTouchEnabled(true);       auto listen = EventListenerTouchOneByOne::create(); listen->onTouchBegan = CC_CALLBACK_2(Layer1::onTouchBegan, this); listen->onTouchMoved = CC_CALLBACK_2(Layer1::onTouchMoved, this); listen->onTouchEnded = CC_CALLBACK_2(Layer1::onTouchEnded, this); listen->onTouchCancelled = CC_CALLBACK_2(Layer1::onTouchCancelled, this); // listen->setSwallowTouches(true); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, this); return true; } bool Layer1::onTouchBegan(Touch *touch, Event * pEvent) { printf("Layer1 began\n");   this->removeFromParent(); this->removeAllChildren(); // for(int i=0;i<100000;i++){ // printf("char=%s",haha.c_str()); // } return true; } void Layer1::onTouchEnded(Touch *touch, Event * pEvent) { printf("Layer1 end\n"); } void Layer1::onTouchCancelled(Touch *touch, Event *pEvent) { printf("Layer1 cancel\n"); } void Layer1::onTouchMoved(Touch *touch, Event *pEvent) { printf("Layer1 Move\n"); }
AppDelegate   auto scene = Scene::create();   auto layer1=Layer1::create();   scene->addChild(layer1);   director->runWithScene(scene);

当点击界面的时候,会报错,看标红的地方,很容易理解什么原因 removeFromParent之后,Layer1实例已经释放了,在调用就会报错(但是在cocos2d-iphone中,他们的顺序是无关紧要的,都可以正确运行,通过调试得知,当调用RemoveFromPanrent的时候,dealloac没有马上调用,而c++中的析构函数会立即调用,我猜想原因可能就在这里吧),然后把顺序反过来,果然正确执行.

下面再看下一个问题,移除Layer1实例的时候,能否只调用removeFromParent,而不调用removeAllChildren().这个可以通过析构函数来判断,新建一个Layer2的类

#ifndef _MAINMENU_H222_#define _MAINMENU_H222_#include "cocos2d.h"using namespace cocos2d;class Layer2 : public Layer{public:    Layer2();       virtual ~Layer2(); bool init(); virtual bool onTouchBegan(Touch *pTouch, Event *pEvent); virtual void onTouchMoved(Touch *pTouch, Event *pEvent); virtual void onTouchEnded(Touch *pTouch, Event *pEvent); virtual void onTouchCancelled(Touch *pTouch, Event *pEvent); CREATE_FUNC(Layer2); }; #endif
#include "Layer2.h"Layer2::Layer2(){}Layer2::~Layer2(){    printf("Layer2析构函数");}bool Layer2::init(){    //this->setTouchEnabled(true);        auto listen = EventListenerTouchOneByOne::create(); listen->onTouchBegan = CC_CALLBACK_2(Layer2::onTouchBegan, this); listen->onTouchMoved = CC_CALLBACK_2(Layer2::onTouchMoved, this); listen->onTouchEnded = CC_CALLBACK_2(Layer2::onTouchEnded, this); listen->onTouchCancelled = CC_CALLBACK_2(Layer2::onTouchCancelled, this); // listen->setSwallowTouches(true); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listen, this); return true; } bool Layer2::onTouchBegan(Touch *touch, Event * pEvent) { printf("Layer2 began\n"); return true; } void Layer2::onTouchEnded(Touch *touch, Event * pEvent) { printf("Layer2 end\n"); // pEvent->stopPropagation(); } void Layer2::onTouchCancelled(Touch *touch, Event *pEvent) { printf("Layer2 cancel\n"); } void Layer2::onTouchMoved(Touch *touch, Event *pEvent) { printf("Layer2 Move\n"); pEvent->stopPropagation(); }

Layer1修改,去掉

this->removeAllChildren();这一行代码

 

Appdelegate

auto scene = Scene::create();      // scene->addChild(MainMenu::create());        auto layer1=Layer1::create();        //int fff=layer1->getReferenceCount();             auto layer2=Layer2::create();    layer1->addChild(layer2); scene->addChild(layer1); // layer2->retain(); // run director->runWithScene(scene);

通过运行发现,Layer2会执行析构函数,那么Layer2是在什么位置被删除的呢,通过看removeFromParent的源码发现,并没有发现删除Layer2的代码,

而在removeAllChildren()中很容易发现是

_children.clear();但是removeFromParent中并没有这个代码,最后通过分析找到了地方,原来Layer的基类Node有一个_children的Vector数组,当

Node释放的时候,他的属性_children也会释放,然后这个属性会调用析构函数,在析构函数里面调用了clear()方法,如下代码

 /** Destructor */

    ~Vector<T>()

    {

        CCLOGINFO("In the destructor of Vector.");

        clear();

    },

,从而使Layer1的孩子Layer2也释放。

所以分析得知,要移除某个cocos2d类的实例,在保证没有内存泄露的情况下(内存泄露的话,两个方法都调也不行),调用 removeFromParent就可删除自身,无需调用removeAllChildren(),如果两个类都想调用,那么先调用removeAllChildren,在调用removeFromParent。

转载于:https://www.cnblogs.com/xiaonanxia/p/5404217.html

你可能感兴趣的文章
a+=b 是什么意思?
查看>>
SilverLight:基础控件使用(5)-TreeView控件-基本使用
查看>>
JSON-JSON 百科
查看>>
一次性从linux发送多个文件到windows
查看>>
powerdesigner辅助导入导出excel文件
查看>>
5月23 注册审核
查看>>
iOS:Core Data 中的简单ORM
查看>>
如何获取e.printStackTrace()的内容
查看>>
nginx入门(4):FastCGI代理
查看>>
学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环
查看>>
使用Maven搭建Struts2框架的开发环境
查看>>
mysql数据库导出导入设置编码
查看>>
下拉菜单(含有阻止事件冒泡)
查看>>
PHP环境搭配
查看>>
[译]时间自动机:语义,算法和工具
查看>>
UVALive 4975 Casting Spells
查看>>
深度学习之Batch Normalization
查看>>
国内开源社区巨作AspectCore-Framework入门
查看>>
51单片机学习笔记(清翔版)(13)——LED点阵、74HC595
查看>>
JavaScript技巧[转载]
查看>>