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 ...
随机推荐
- select document library from certain list 分类: Sharepoint 2015-07-05 07:52 6人阅读 评论(0) 收藏
S using System; using Microsoft.SharePoint; namespace Test { class ConsoleApp { static void Main(str ...
- 从0到1---“保多多”APP的开发(二)
今天继续记录宝多多开发过程中的一些值得注意的知识点: 1.验证车牌格式的正则表达式函数: //车牌号验证 - (BOOL)validateCarNo:(NSString *)carNo { NSStr ...
- C#面向对象学习笔记概要
1.面向对象不是取代面向过程的. 2.面向对象的三个特性:封装.继承.多态. 3.字段.方法.属性(后面讲)都可以叫做类的成员,他们都需要定义访问级别.访问级别的用处在于控制成员在哪些地方可以被访问, ...
- git 创建版本库
服务器安装后git后 1.在repositories仓库文件夹中执行git init aa.git --bare 创建aa的中心库(注意建立aa版本库时当前登录用户必须为git的相关用户,并保证/d ...
- Hadoop数据类型介绍
我们知道hadoop是由Java 编程写的.因此我们使用Java开发环境来操作HDFS,编写mapreduce也是很自然的事情.但是这里面hadoop却对Java数据类型进行了包装,那么hadoop的 ...
- PHPExcel 导出表格 不知道好不好用
PHPExcel类是php一个excel表格处理插件了,下面我来给大家介绍利用PHPExcel类来导入与导出excel表格的应用方法,有需要了解的朋友不防参考参考(PHPExcel自己百度下载这里不介 ...
- Divisors
计算小于n的数中,约数个数最多的数,若有多个最输出最小的一个数. http://hihocoder.com/problemset/problem/1187 对于100有 60 = 2 * 2 * 3 ...
- [转]lua面向对象编程之点号与冒号的差异详细比较
首先,先来一段在lua创建一个类与对象的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Class = {} Class.__index = Cl ...
- Linux线程-终止
在前文讨论了线程创建的一些基本东西,这里讨论有哪些方法可以使线程终止,线程终止又是如何与创建所需的参数进行关联的. 一,正常终止 线程在执行完成之后,正常终止. 二,线程取消 2.1 线程取消的定义 ...
- Sprint第二个冲刺(第十二天)
一.Sprint 计划会议: 现在商家上传商品的图片的功能已经完成了,正在准备是实现更新商品图片.更新商品价格和商品描述得功能,目前工作进展顺利,进度也慢慢赶上,争取顺利完成目标. 下面是真机测试下的 ...