cocos2d-x遊戲開發(六)自動釋放池

來源:互聯網
上載者:User

歡迎轉載:http://blog.csdn.net/fylz1125/article/details/8519887


上一篇文章寫了引用計數和自動釋放的大概流程,其中略過了自動釋放池,這裡簡單述說。

前面提到CCObject的autorelease函數

CCObject* CCObject::autorelease(void){    CCPoolManager::sharedPoolManager()->addObject(this);    return this;}

這裡的sharedPoolManager()函數表明CCPoolManager是個單例類。

題外話:cocos2d-x裡面大量的用到了單例模式,每個單例類都有個明顯的標誌,就是它的執行個體擷取函數,從命名規則上看都是sharedxxx()形式。

跟進這個addObject函數

void CCPoolManager::addObject(CCObject* pObject){    getCurReleasePool()->addObject(pObject);}

這裡就到了CCPoolManager,來看下這個類

class CC_DLL CCPoolManager{    CCArray*    m_pReleasePoolStack;        CCAutoreleasePool*                    m_pCurReleasePool;    CCAutoreleasePool* getCurReleasePool();public:    CCPoolManager();    ~CCPoolManager();    void finalize();    void push();    void pop();    void removeObject(CCObject* pObject);    void addObject(CCObject* pObject);    static CCPoolManager* sharedPoolManager();    static void purgePoolManager();    friend class CCAutoreleasePool;};

這裡可以看到它維護一個自動釋放池CCAutoreleasePool,還有個CCArray變數,是個棧結構,來管理自動釋放池。

看下實現:

#include "CCAutoreleasePool.h"#include "ccMacros.h"NS_CC_BEGIN// 自動釋放池管理員執行個體static CCPoolManager* s_pPoolManager = NULL;CCAutoreleasePool::CCAutoreleasePool(void){    m_pManagedObjectArray = new CCArray(); // 自動釋放的對象放在這個Array裡面    m_pManagedObjectArray->init();}CCAutoreleasePool::~CCAutoreleasePool(void){    CC_SAFE_DELETE(m_pManagedObjectArray);}void CCAutoreleasePool::addObject(CCObject* pObject){    m_pManagedObjectArray->addObject(pObject);// 實質上的添加函數,加到對象管理數組裡面    CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");//斷言    ++(pObject->m_uAutoReleaseCount);    pObject->release(); // no ref count, in this case autorelease pool added.}void CCAutoreleasePool::removeObject(CCObject* pObject){    for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i)    {        m_pManagedObjectArray->removeObject(pObject, false);    }}void CCAutoreleasePool::clear(){    if(m_pManagedObjectArray->count() > 0)    {        //CCAutoreleasePool* pReleasePool;#ifdef _DEBUG        int nIndex = m_pManagedObjectArray->count() - 1;#endif        CCObject* pObj = NULL;        CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj)        {            if(!pObj)                break;            --(pObj->m_uAutoReleaseCount);            //(*it)->release();            //delete (*it);#ifdef _DEBUG            nIndex--;#endif        }        m_pManagedObjectArray->removeAllObjects();    }}//--------------------------------------------------------------------//// CCPoolManager////--------------------------------------------------------------------CCPoolManager* CCPoolManager::sharedPoolManager()// 擷取管理員執行個體{    if (s_pPoolManager == NULL)    {        s_pPoolManager = new CCPoolManager();// 如果沒有執行個體,調建構函式    }    return s_pPoolManager;}void CCPoolManager::purgePoolManager(){    CC_SAFE_DELETE(s_pPoolManager);}CCPoolManager::CCPoolManager(){    m_pReleasePoolStack = new CCArray();    // 棧結構,管理自動釋放池    m_pReleasePoolStack->init();    m_pCurReleasePool = 0;}CCPoolManager::~CCPoolManager(){         finalize();      // we only release the last autorelease pool here     m_pCurReleasePool = 0;     m_pReleasePoolStack->removeObjectAtIndex(0);      CC_SAFE_DELETE(m_pReleasePoolStack);}void CCPoolManager::finalize(){    if(m_pReleasePoolStack->count() > 0)    {        //CCAutoreleasePool* pReleasePool;        CCObject* pObj = NULL;        CCARRAY_FOREACH(m_pReleasePoolStack, pObj) //遍曆對象池棧,清空所有對象池        {            if(!pObj)                break;            CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;            pPool->clear();        }    }}void CCPoolManager::push() //管理員的push方法,將對象池棧壓棧。當前對象池為NULL時才調用push函數{    CCAutoreleasePool* pPool = new CCAutoreleasePool();       //ref = 1    m_pCurReleasePool = pPool;    m_pReleasePoolStack->addObject(pPool);                   //ref = 2    pPool->release();                                       //ref = 1}void CCPoolManager::pop() // 管理員的pop方法,將對象池棧彈棧,其實就是釋放對象{    if (! m_pCurReleasePool)    {        return;    }     int nCount = m_pReleasePoolStack->count();    m_pCurReleasePool->clear();       if(nCount > 1)      {        m_pReleasePoolStack->removeObjectAtIndex(nCount-1);//         if(nCount > 1)//         {//             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);//             return;//         }        m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);    }    /*m_pCurReleasePool = NULL;*/}void CCPoolManager::removeObject(CCObject* pObject){    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");    m_pCurReleasePool->removeObject(pObject);}void CCPoolManager::addObject(CCObject* pObject){    getCurReleasePool()->addObject(pObject);// 將對象添加到當前的對象池}CCAutoreleasePool* CCPoolManager::getCurReleasePool() // 擷取當前對象池,{    if(!m_pCurReleasePool)    {        push();// 對象池由一個棧維護。當前對象池為空白,則push一下,push函數會new一個對象池,然後添加到棧裡    }    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");    return m_pCurReleasePool;}NS_CC_END

好了,就這些。

一個對象添加到自動釋放池後在什麼時機被釋放,這裡不寫了。後面有機會再寫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.