zoukankan      html  css  js  c++  java
  • cocos2dx 内存管理的理解

      关于引擎内存管理的细节,网上有大量的详解,这里概括一下:

    cocos2d-x 的世界是基于 CCObject 类构建的,所以内存管理的本质就是管理一个个 CCObject。

    //CCObject 内部维护着一个引用计数,引用计数为 0 就自动释放
    unsigned int m_uReference;
    //管理内存的实质就是管理这些 “引用计数” 了,使用 retain 和 release 方法对引用计数进行操作
    void release(void);//引用计数:--m_uReference
    void retain(void); //引用计数:++m_uReference
    CCObject* autorelease(void);

    这里引入了自动释放池的概念,它的作用是:每一帧都检测池中对象的引用计数。为什么需要它?

    >>使用create创建一个对象时候,我们可能并不立即使用,这时为了保证在使用之前不会被释放掉,就让它存活一帧,所以初始引用计数为1。

    >>如果当前帧结束了,仍然没有使用,则在帧过渡时,自动释放池会遍历池中的对象,使其引用计数-1,释放掉对象,所以下一帧就不存在了。

    //初始化一个对象
    static CCObject* create()
    {
      //new CCObject 对象
      CCObject *pRet = new CCObject();
        if (pRet && pRet->init())
        {
            //添加到自动释放池
            pRet->autorelease();
            return pRet;
        }
        else
        {
            delete pRet;
            pRet = 0;
            return 0;
        }
    }
    
    //我们看到初始化的对象 自引用 m_uReference = 1
    CCObject::CCObject(void)
    :m_uAutoReleaseCount(0)
    ,m_uReference(1) // when the object is created, the reference count of it is 1
    ,m_nLuaID(0)
    {
        static unsigned int uObjectCount = 0;
        m_uID = ++uObjectCount;
    }
    
    //标记为自动释放对象
    CCObject* CCObject::autorelease(void)
    {
        //添加到自动释放池
        CCPoolManager::sharedPoolManager()->addObject(this);
        return this;
    }

    由此可见,创建的对象如果没有使用,则会交由自动释放池自动释放掉,不需要担心。那如何才算使用了呢?

    》任何导致引用计数增加++(>1)的行为都算是使用了:

    CCNode* node = CCNode::create()
    //方式一:retain
    CCSprite* sp = CCSprite::create("a.png");
    sp->retain(); //如果不retain,以后就用不到了
    //方式二:交给父类,隐式retian
    node->addChild(sp);//此时它的释放由它的父类来管理了
    node->setSprite(sp);//或者赋值给成员变量

    最后列几个需要注意的地方:

    1>CCArray创建之后,需要retain,在使用该数组的类中析构函数中release它。

    2>new出来的对象,即不采用cocos2dx内置的内存管理方式时,尤其要注意手动释放delete,因为它没有添加到自动释放池中,导致初始时的引用计数1没有释放。

    3>new和create的一个重大区别:没有走父类的init()函数。有些父类(例Widget)在init()中做了一些初始工作,此时new出来的对象缺少这部分操作(有些成员没有初始化),在释放的时候会报错。这种情况主要发生在new一个CCNode及其子类对象的身上。

  • 相关阅读:
    new
    如何在win7上面安装python的包
    进程
    网络编程模块的使用
    面向对象基础与实例
    类与对象的属性与使用方法
    基础面向对象与面向过程
    RE模块垃圾回收机制
    常用函数模块
    thinkphp6 find_in_set使用实例
  • 原文地址:https://www.cnblogs.com/gl5773477/p/4404753.html
Copyright © 2011-2022 走看看