cocos2d-x游戏开发自动释放池

发表于2015-12-03
评论0 438浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594

前面提到CCObject的autorelease函数

  1. CCObject* CCObject::autorelease(void)  
  2. {  
  3.     CCPoolManager::sharedPoolManager()->addObject(this);  
  4.     return this;  
  5. }  

这里的sharedPoolManager()函数表明CCPoolManager是个单例类。

题外话:cocos2d-x里面大量的用到了单例模式,每个单例类都有个明显的标志,就是它的实例获取函数,从命名规则上看都是sharedxxx()形式。

跟进这个addObject函数

  1. void CCPoolManager::addObject(CCObject* pObject)  
  2. {  
  3.     getCurReleasePool()->addObject(pObject);  
  4. }  

这里就到了CCPoolManager,来看下这个类

  1. class CC_DLL CCPoolManager  
  2. {  
  3.     CCArray*    m_pReleasePoolStack;      
  4.     CCAutoreleasePool*                    m_pCurReleasePool;  
  5.   
  6.     CCAutoreleasePool* getCurReleasePool();  
  7. public:  
  8.     CCPoolManager();  
  9.     ~CCPoolManager();  
  10.     void finalize();  
  11.     void push();  
  12.     void pop();  
  13.   
  14.     void removeObject(CCObject* pObject);  
  15.     void addObject(CCObject* pObject);  
  16.   
  17.     static CCPoolManager* sharedPoolManager();  
  18.     static void purgePoolManager();  
  19.   
  20.     friend class CCAutoreleasePool;  
  21. };  
这里可以看到它维护一个自动释放池CCAutoreleasePool,还有个CCArray变量,是个栈结构,来管理自动释放池。

看下实现:

  1. #include "CCAutoreleasePool.h"  
  2. #include "ccMacros.h"  
  3.   
  4. NS_CC_BEGIN  
  5. // 自动释放池管理员实例  
  6. static CCPoolManager* s_pPoolManager = NULL;  
  7.   
  8. CCAutoreleasePool::CCAutoreleasePool(void)  
  9. {  
  10.     m_pManagedObjectArray = new CCArray(); // 自动释放的对象放在这个Array里面  
  11.     m_pManagedObjectArray->init();  
  12. }  
  13.   
  14. CCAutoreleasePool::~CCAutoreleasePool(void)  
  15. {  
  16.     CC_SAFE_DELETE(m_pManagedObjectArray);  
  17. }  
  18.   
  19. void CCAutoreleasePool::addObject(CCObject* pObject)  
  20. {  
  21.     m_pManagedObjectArray->addObject(pObject);// 实质上的添加函数,加到对象管理数组里面  
  22.   
  23.     CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");//断言  
  24.     ++(pObject->m_uAutoReleaseCount);  
  25.     pObject->release(); // no ref count, in this case autorelease pool added.  
  26. }  
  27.   
  28. void CCAutoreleasePool::removeObject(CCObject* pObject)  
  29. {  
  30.     for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i)  
  31.     {  
  32.         m_pManagedObjectArray->removeObject(pObject, false);  
  33.     }  
  34. }  
  35.   
  36. void CCAutoreleasePool::clear()  
  37. {  
  38.     if(m_pManagedObjectArray->count() > 0)  
  39.     {  
  40.         //CCAutoreleasePool* pReleasePool;  
  41. #ifdef _DEBUG  
  42.         int nIndex = m_pManagedObjectArray->count() - 1;  
  43. #endif  
  44.   
  45.         CCObject* pObj = NULL;  
  46.         CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj)  
  47.         {  
  48.             if(!pObj)  
  49.                 break;  
  50.   
  51.             --(pObj->m_uAutoReleaseCount);  
  52.             //(*it)->release();  
  53.             //delete (*it);  
  54. #ifdef _DEBUG  
  55.             nIndex--;  
  56. #endif  
  57.         }  
  58.   
  59.         m_pManagedObjectArray->removeAllObjects();  
  60.     }  
  61. }  
  62.   
  63.   
  64. //--------------------------------------------------------------------  
  65. //  
  66. // CCPoolManager  
  67. //  
  68. //--------------------------------------------------------------------  
  69.   
  70. CCPoolManager* CCPoolManager::sharedPoolManager()// 获取管理员实例  
  71. {  
  72.     if (s_pPoolManager == NULL)  
  73.     {  
  74.         s_pPoolManager = new CCPoolManager();// 如果没有实例,调构造函数  
  75.     }  
  76.     return s_pPoolManager;  
  77. }  
  78.   
  79. void CCPoolManager::purgePoolManager()  
  80. {  
  81.     CC_SAFE_DELETE(s_pPoolManager);  
  82. }  
  83.   
  84. CCPoolManager::CCPoolManager()  
  85. {  
  86.     m_pReleasePoolStack = new CCArray();    // 栈结构,管理自动释放池  
  87.     m_pReleasePoolStack->init();  
  88.     m_pCurReleasePool = 0;  
  89. }  
  90.   
  91. CCPoolManager::~CCPoolManager()  
  92. {  
  93.       
  94.      finalize();  
  95.    
  96.      // we only release the last autorelease pool here   
  97.     m_pCurReleasePool = 0;  
  98.      m_pReleasePoolStack->removeObjectAtIndex(0);  
  99.    
  100.      CC_SAFE_DELETE(m_pReleasePoolStack);  
  101. }  
  102.   
  103. void CCPoolManager::finalize()  
  104. {  
  105.     if(m_pReleasePoolStack->count() > 0)  
  106.     {  
  107.         //CCAutoreleasePool* pReleasePool;  
  108.         CCObject* pObj = NULL;  
  109.         CCARRAY_FOREACH(m_pReleasePoolStack, pObj) //遍历对象池栈,清空所有对象池  
  110.         {  
  111.             if(!pObj)  
  112.                 break;  
  113.             CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;  
  114.             pPool->clear();  
  115.         }  
  116.     }  
  117. }  
  118.   
  119. void CCPoolManager::push() //管理员的push方法,将对象池栈压栈。当前对象池为NULL时才调用push函数  
  120. {  
  121.     CCAutoreleasePool* pPool = new CCAutoreleasePool();       //ref = 1  
  122.     m_pCurReleasePool = pPool;  
  123.   
  124.     m_pReleasePoolStack->addObject(pPool);                   //ref = 2  
  125.   
  126.     pPool->release();                                       //ref = 1  
  127. }  
  128.   
  129. void CCPoolManager::pop() // 管理员的pop方法,将对象池栈弹栈,其实就是释放对象  
  130. {  
  131.     if (! m_pCurReleasePool)  
  132.     {  
  133.         return;  
  134.     }  
  135.   
  136.      int nCount = m_pReleasePoolStack->count();  
  137.   
  138.     m_pCurReleasePool->clear();  
  139.    
  140.       if(nCount > 1)  
  141.       {  
  142.         m_pReleasePoolStack->removeObjectAtIndex(nCount-1);  
  143.   
  144. //         if(nCount > 1)  
  145. //         {  
  146. //             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);  
  147. //             return;  
  148. //         }  
  149.         m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);  
  150.     }  
  151.   
  152.     /*m_pCurReleasePool = NULL;*/  
  153. }  
  154.   
  155. void CCPoolManager::removeObject(CCObject* pObject)  
  156. {  
  157.     CCAssert(m_pCurReleasePool, "current auto release pool should not be null");  
  158.   
  159.     m_pCurReleasePool->removeObject(pObject);  
  160. }  
  161.   
  162. void CCPoolManager::addObject(CCObject* pObject)  
  163. {  
  164.     getCurReleasePool()->addObject(pObject);// 将对象添加到当前的对象池  
  165. }  
  166.   
  167.   
  168. CCAutoreleasePool* CCPoolManager::getCurReleasePool() // 获取当前对象池,  
  169. {  
  170.     if(!m_pCurReleasePool)  
  171.     {  
  172.         push();// 对象池由一个栈维护。当前对象池为空,则push一下,push函数会new一个对象池,然后添加到栈里  
  173.     }  
  174.   
  175.     CCAssert(m_pCurReleasePool, "current auto release pool should not be null");  
  176.   
  177.     return m_pCurReleasePool;  
  178. }  
  179.   
  180. NS_CC_END  

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台