cocos2dx3.0 removeFromParent和removeAllChildren含义
顾名思义,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。
cocos2dx3.0 removeFromParent和removeAllChildren含义的更多相关文章
- Cocos2d-X3.0 刨根问底(七)----- 事件机制Event源码分析
这一章,我们来分析Cocos2d-x 事件机制相关的源码, 根据Cocos2d-x的工程目录,我们可以找到所有关于事件的源码都存在放在下图所示的目录中. 从这个event_dispatcher目录中的 ...
- linux中shell变量$#,$@,$0,$1,$2的含义解释
linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行 ...
- Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解
作为重量级的跨平台开发的游戏引擎,Cocos2d-x在现今的手游开发领域占有重要地位.那么问题来了,作为Cocos2dx的学习者,它的可移植特性我们就需要掌握,要不然总觉得少一门技能.然而这个时候各种 ...
- Cocos2d-X3.0 刨根问底(八)----- 场景(Scene)、层(Layer)相关源码分析
本章节我们重点分析Cocos2d-x3.0与 场景.层相关的源码.这部分源码集中在 libcocos2d –> layers_scenes_transitions_nodes目录下面 我先发个截 ...
- Cocos2d-X3.0 刨根问底(一)----- 概览
罗嗦几句,本系列文章记录了小鱼(本人)自学Cocos2D-X的整个过程,主要从分析Cocos2D-x的源码方式来学习Cocos2d-x这样一个优秀的游戏引擎架构,本着不但要知其然还要知其所以然的学习态 ...
- Mac下cocos2dx-3.0打包Android时,提示"SimpleAudioEngine.h"not found的解决方法
前段时间触控公布cocos2dx-3.0,在升级之后试过之后,在最初的不习惯之后,感觉比之前的好用了不少,在下之前一直是用xCode模板创建,这回算是一口气升到顶了. 之后再一次编程时须要用到Sima ...
- cocos2d-x3.0+Eclipse配置说明
假如我们已经装了JavaJDK.Cygwin,也解压了2013-08-27之后最新的AndroidSDK,其实最新的AndroidSDK已经集成了eclipse,eclipse里面已经配置好了Andr ...
- linux中shell变量$#,$@,$0,$1,$2的含义解释
linux中shell变量$#,$@,$0,$1,$2的含义解释 linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: $$ Shell本身的PID(ProcessID ...
- Cocos2d-x3.0游戏实例之《别救我》第二篇——创建物理世界
这篇我要给大家介绍两个知识点: 1. 创建游戏物理世界 2. 没了(小若:我噗) 害怕了?不用操心.这太简单了~! 笨木头花心贡献.啥?花心?不呢.是用心~ 转载请注明,原文地址:http://www ...
随机推荐
- CSS强制中英文换行与不换行
1. word-break:break-all; 只对英文起作用,以字母作为换行依据 2. word-wrap:break-word; 只对英文起作用,以单词作为换行依据 3. white-space ...
- rails之 Migrations (转)
1.简介 在rails中用migration可以很方便的管理数据库的结构.可以创建数据库,创建表,删除表,添加字段,删除字段,整理数据. migration就是一系列的class,这些类都继承了Act ...
- OrCAD搭建Access数据库
刚进入到一个小公司,接到的第一个电路设计的案子是从零开始的,辛苦就不说,关键是这么不严谨,容易出错,于是乎,问题来了,能否从零开始着手建立个类似于以前公司的数据库,管理原理图封装,PCB封装及规格书! ...
- HDU1005(矩阵快速幂)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 #include<cstdio> using namespace std; int ...
- Day17_集合第三天
1.HashSet类(掌握) 1.哈希值概念 哈希值:哈希值就是调用对象的hashCode()方法后返回的一个int型数字 哈希桶:简单点理解就是存储相同哈希值对象的一个容器 1. ...
- 关于 Unix 用户权限及进程权限及 Saved set-user-id
最近在看APUE,看到3.14节,fcntl的时候#include <fcntl.h>int fcntl(int fd, int cmd, .../* int arg */);出错返回-1 ...
- Gvim+Emmet.vim 那些事。
转自:http://www.jianshu.com/p/67fa1e2114c5 背景 HTML和CSS的写法相对固定,而且重复的工作特别多,特别是尖括号实在是很烦.使用Emmet至少能帮你节省一半的 ...
- Selenium 中 cssSelector定位
一.为什么使用cssSelector定位元素? 目前针对一些常规定位方式有:By.id.By.name.By.LinkTest(针对<a>标签).By.ClassName 针对不太好定位的 ...
- 线段树 hdu4046
Panda Time Limit: 10000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- Android学习六:Socket 使用
1socket的作用 通过http去获取服务器的数据在有些情况下是行不通的,所有使用socket与服务器通信也是必须掌握的 2.代码 好了上代码,代码中有解释,首先是简单的服务端代码 package ...