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。

  • 相关阅读:
    poj 1743 Musical Theme 后缀数组
    poj 1743 Musical Theme 后缀数组
    cf 432D Prefixes and Suffixes kmp
    cf 432D Prefixes and Suffixes kmp
    hdu Data Structure? 线段树
    关于position和anchorPoint之间的关系
    ios POST 信息
    CALayers的代码示例
    CALayers详解
    ios中得sqlite使用基础
  • 原文地址:https://www.cnblogs.com/xiaonanxia/p/5404217.html
Copyright © 2011-2022 走看看