歡迎轉載: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
好了,就這些。
一個對象添加到自動釋放池後在什麼時機被釋放,這裡不寫了。後面有機會再寫。