zoukankan      html  css  js  c++  java
  • 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
    ");
        
       
        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
    ");
    }
    
    void Layer1::onTouchCancelled(Touch *touch, Event *pEvent)
    {
        printf("Layer1 cancel
    ");
    }
    
    void Layer1::onTouchMoved(Touch *touch, Event *pEvent)
    {
        printf("Layer1 Move
    ");
    }
    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
    ");
        
        
        return true;
    }
    
    void Layer2::onTouchEnded(Touch *touch, Event * pEvent)
    {
         printf("Layer2 end
    ");
        // pEvent->stopPropagation();
    }
    
    void Layer2::onTouchCancelled(Touch *touch, Event *pEvent)
    {
         printf("Layer2 cancel
    ");
    }
    
    void Layer2::onTouchMoved(Touch *touch, Event *pEvent)
    {
        printf("Layer2 Move
    ");
        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。

  • 相关阅读:
    .NET实时2D渲染入门·动态时钟
    JAVA中抽象类的使用
    R语言中函数调试
    利用Bioperl的SeqIO模块解析fastq文件
    ASCII码表
    JAVA 中转义符的理解
    在线引物设计网站,老板推荐的,亲测好用
    列出一个买东西的好网站,值得推荐
    R语言集合操作
    R语言do.call 函数用法详解
  • 原文地址:https://www.cnblogs.com/xiaonanxia/p/5404217.html
Copyright © 2011-2022 走看看