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 ... 
随机推荐
- Django+python+BeautifulSoup垂直搜索爬虫
			http://blog.sina.com.cn/s/blog_709475a10100wmln.html 
- Sql获取第一天、最后一天
			昨天面试一家公司,上机题目中要求获取每月最后一笔订单.用到了日期的选择性查询,回来在ITeye上找到了这篇文章. 原文: http://new-fighter.iteye.com/blog/17587 ... 
- C#常用操作类库三(XML操作类)
			/// <summary> /// XmlHelper 的摘要说明. /// xml操作类 /// </summary> public class XmlHelper { pr ... 
- 怎样禁用或启用"最近使用的项目"
			1.右击“任务栏”——属性——‘开始’菜单——自定义——高级——去掉“列出我最近打开的文档”的勾选——确定.2.通过“组策略”来修改开始——运行——gpedit.msc——用户配置——管理模板——任务 ... 
- ios项目接入sdk事项
			使用cocos2d-x引擎创建的项目在xcode里可以看到都带有一个ios目录,把要接入的sdk的包含.framework库文件和.bundle的资源文件的父目录拖入到xcode项目里的这个ios目录 ... 
- 网络数据包收发流程(四):协议栈之packet_type
			进入函数netif_receive_skb()后,skb正式开始协议栈之旅.先上图,协议栈大致过程如下所示:跟OSI七层模型不同,linux根据包结构对网络进行分层.比如,arp头和ip头都是紧跟在以 ... 
- VS 2013 打包程序教程
			简述 如果你只是想要在他人的机子上运行你的程序而不想安装,有一种简单的方法,只要使用本教程的“步骤—3.生成Release 文件夹”即可.但是有一点需要注意,如果你在程序中调用了其他的dll,那么你需 ... 
- Java笔记4-do while循环,break,修饰符,方法的调用
			do while循环语法:do{ //循环体}while(条件表达式); 注:它是先执行循环体,后再判断的循环结构. 如:int i = 0;do{ System.out.println(" ... 
- oracle字符函数
			UPPER(char) 小写转大写 LOWER(char) 大写转小写 INITCAP(char) 首字母转换 SUBSTR(char,[m[,n]]) 截取字符串函数 从源字符串char的m开始截取 ... 
- windows多线程相关
			1.多线程同步的方法 a)entercirticalsection leaveciriticalsection b)Mutex互斥对象 waitforsingleobject releasemutex ... 
