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

来源:互联网 发布:重庆优化公司哪家好 编辑:程序博客网 时间:2024/05/16 04:50

欢迎转载:http://blog.csdn.net/fylz1125/article/details/8519887 


上一篇文章写了引用计数和自动释放的大概流程,其中略过了自动释放池,这里简单述说。

前面提到CCObject的autorelease函数

[cpp] view plaincopyprint?
  1. CCObject* CCObject::autorelease(void)  
  2. {  
  3.     CCPoolManager::sharedPoolManager()->addObject(this);  
  4.     return this;  
  5. }  

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

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

跟进这个addObject函数

[cpp] view plaincopyprint?
  1. void CCPoolManager::addObject(CCObject* pObject)  
  2. {  
  3.     getCurReleasePool()->addObject(pObject);  
  4. }  

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

[cpp] view plaincopyprint?
  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变量,是个栈结构,来管理自动释放池。

看下实现:

[cpp] view plaincopyprint?
  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  

好了,就这些。

一个对象添加到自动释放池后在什么时机被释放,这里不写了。后面有机会再写。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脸一躺下就丑怎么办 身体淤堵的厉害怎么办 怀孕晚期脚肿了怎么办 宝宝感冒咳嗽流鼻涕流泪怎么办 孕晚期睡觉习惯面朝右怎么办 鼻涕一直不停的流怎么办 宝宝一直流清鼻涕怎么办 感冒了眼睛酸胀流泪怎么办 五个月宝宝感冒流鼻涕怎么办 六个月宝宝感冒流鼻涕怎么办 一岁宝宝感冒咳嗽流鼻涕怎么办 七个月宝宝感冒流鼻涕咳嗽怎么办 孩子握笔姿势不正确怎么办 走久了脚底板痛怎么办 不会给宝宝拍嗝怎么办 打了肉毒素淤青怎么办 新生儿一吃母乳就睡觉怎么办 10岁半宝宝缺钾怎么办 宝宝吃不到乳晕怎么办 喂母乳乳头破了怎么办 宝宝吸了乳头痛怎么办 喂母乳奶头很疼怎么办 孩子吸的乳头痛怎么办 新生儿一直睡觉不吸吮怎么办 新生儿光睡觉不吃奶怎么办 婴儿不吸母亲的奶怎么办 肾里有结石一直不掉下来怎么办 宝宝拍不出来嗝怎么办 未满月宝宝溢奶怎么办 吃母乳老是吐奶怎么办 宝宝吃母乳吐奶怎么办 新生儿三天没大便了怎么办 奶水多宝宝呛奶怎么办 婴儿的含乳姿势不正确怎么办 一个月竖着抱了怎么办 乳头被婴儿吸痛怎么办 婴儿从鼻孔吐奶怎么办 宝宝习惯含着乳头睡觉怎么办? 宝宝习惯奶瓶不吃乳头怎么办 婴儿从鼻子吐奶怎么办 宝宝从鼻孔出奶怎么办