cocos 自动内存管理分析

#include "CCAutoreleasePool.h"
#include "ccMacros.h"

NS_CC_BEGIN

static CCPoolManager* s_pPoolManager = NULL;

CCAutoreleasePool::CCAutoreleasePool(void)
{
    m_pManagedObjectArray = new CCArray();
    m_pManagedObjectArray->init();
}

CCAutoreleasePool::~CCAutoreleasePool(void)
{
    CC_SAFE_DELETE(m_pManagedObjectArray);
}

void CCAutoreleasePool::addObject(CCObject* pObject)//添加对象,再释放一次,对象的引用为1
{
    m_pManagedObjectArray->addObject(pObject);//1+1

    CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");
    ++(pObject->m_uAutoReleaseCount);
    pObject->release(); // -1
}

void CCAutoreleasePool::removeObject(CCObject* pObject)
{
    for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i)
    {
        m_pManagedObjectArray->removeObject(pObject, false);
    }
}

void CCAutoreleasePool::clear()//清理上帧自动管理的对象(每个obj的引用-1)
{
    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 用于储存 CCAutoreleasePool
{
    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()//创建一个 m_pCurReleasePool 添加到 m_pReleasePoolStack
{
    CCAutoreleasePool* pPool = new CCAutoreleasePool();       //ref = 1
    m_pCurReleasePool = pPool;

    m_pReleasePoolStack->addObject(pPool);                   //ref = 2

    pPool->release();                                       //ref = 1
}

void CCPoolManager::pop()//每帧执行一次,如果 m_pReleasePoolStack 有则开始清理。
{
    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()//获取本帧的 m_pCurReleasePool ,每帧的m_pCurReleasePool都是新的(因为被清了)
{
    if(!m_pCurReleasePool)
    {
        push();
    }

    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");

    return m_pCurReleasePool;
}

NS_CC_END

 

大致思路就是:有CCPoolManager  与CCAutoreleasePool

程序是按帧,一帧一帧运行的

每帧执行的程序创建的obj如果使用了autorelease(CCObject的)会将obj添加到CCAutoreleasePool,这个在本帧惟一的,CCAutoreleasePool会被添加到CCPoolManager

每次mainLoop会执行内存清理(CCPoolManager的pop) 对上一帧保存的对象release 。也可以说是CCPoolManager 删除上次的CCAutoreleasePool。 如果上一帧的对象引用为1(初始为1)就会被释放掉。大于1不会被释放,但也不会再管了。

 

如果obj被添加到CCAutoreleasePool obj的m_uAutoReleaseCount会+1,直到从CCAutoreleasePool删除时-1.

 

 

 

posted @ 2013-12-03 20:50  晨祷  阅读(491)  评论(0编辑  收藏  举报