zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    Mac终端学习C笔记
    苹果双系统win8.1遇到的一些问题
    初学者Android studio安装
    java八种排序算法---直接插入排序
    java八种排序算法---快速排序
    java的八种排序算法---冒泡排序
    转利用 NPOI 變更字體尺寸及樣式
    AJAX 跨域调用WEB API(转)
    常用C#字符串函数大全
    C# 发送邮件整理,包括控制台程序、WPF、WebForm 及 ASP.NET MVC
  • 原文地址:https://www.cnblogs.com/mattins/p/3456501.html
Copyright © 2011-2022 走看看