cocos2d-x内存管理机制剖析

         cocos2d-x的内存管理机制是基于一种引用计数的思想,类中有一个变量保存引用该对象的模块个数,对象被从堆上创建时,引用计数默认为1; 如果有模块需要引用该对象,将它引用计数加1;不需要引用时,将引用计数减1,引用计数为0时释放该对象。

        cocos2d-x引用计数功能集成在CCObject类,核心源码如下:

头文件:

class CCObject
{
protected:
    // 引用计数
    unsigned int        m_uReference;
    // 是否自动释放
    bool        m_bManaged;  
};

源文件:

/*
 * 不需引用对象时调用
 */
void CCObject::release(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");
    --m_uReference;

    if (m_uReference == 0)
    {
        delete this;
    }
}

/*
 * 引用对象时调用
 */
void CCObject::retain(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");
    ++m_uReference;
}
/*
 * 自动释放,加入内存释放池
 */
CCObject* CCObject::autorelease(void)
{
    CCPoolManager::sharedPoolManager()->addObject(this);

    m_bManaged = true;
    return this;
}

      类需要使用引用计数功能时继承CCObject类,从堆上创建对象,引用默认为1,如果不想显式释放对象,可以将对象加入到内存释放池,cocos2d-x内存管理模块会在每一帧调用内存释放池释放加入到池中的对象。

       cocos2d-x内存管理模块核心源如下:

头文件:

/**
 * @addtogroup base_nodes
 *             默认释放池
 */
class CC_DLL CCAutoreleasePool : public CCObject
{
    CCArray*    m_pManagedObjectArray;    
public:
    CCAutoreleasePool(void);
    ~CCAutoreleasePool(void);

    void addObject(CCObject *pObject);
    void removeObject(CCObject *pObject);

    /*释放池中所有对象*/
    void clear();
};

/*
 * 释放池管理模块
 */
class CC_DLL CCPoolManager
{
    /*程序结束时调用,释放所有池中的对象*/
    void finalize();

    /*增加内存池,在主程序启动时调用*/
    void push();
  
   /*每一帧、程序退出时调用, 释放内存池对象,当内存池个数大于1时,同时释放内存池*/
    void pop();
    
    /*从内存池中删除对象*/
    void removeObject(CCObject* pObject);

    /*把对象加入到内存池中*/
    void addObject(CCObject* pObject);

    static CCPoolManager* sharedPoolManager();

    /*程序退出时调用*/
    static void purgePoolManager();

};

CCDirector.cpp代码片段:

bool CCDirector::init(void)
{
    ...
        // create autorelease pool
    CCPoolManager::sharedPoolManager()->push();
    ...
}
CCDirector::~CCDirector(void)
{
    ...
    // pop the autorelease pool
    CCPoolManager::sharedPoolManager()->pop();
    CCPoolManager::purgePoolManager();
    ...
}

    为了省略不相关的代码使用[...]符号

CCDisplayLinkDirector.cpp代码片段:

void CCDisplayLinkDirector::mainLoop(void)
{
    if (m_bPurgeDirecotorInNextLoop)
    {
        m_bPurgeDirecotorInNextLoop = false;
        purgeDirector();
    }
    else if (! m_bInvalid)
     {
         drawScene();
     
         // release the objects
         CCPoolManager::sharedPoolManager()->pop();        
     }
}

mainLoop函数在每帧时调用,函数再调用 CCPoolManager::sharedPoolManager()->pop();  释放当前池的所有对象 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值