coco2dx内存管理(源码版本:cocos2d-x-2.2.3)
来源:互联网 发布:怎么挑选电子琴知乎 编辑:程序博客网 时间:2024/06/05 02:07
深入的了解cocos2dx内存管理可以知道cocos2dx在这方面所做的动作,这样可以减少在开发的时候遇到的意料之外的错误。
cocos2dx的内存管理类名叫:CCobject。这个类用到的地方非常多,甚至可以说这个类是所有cocos2dx类的基类。虽然也有一些类没有从这个类继承内存管理功能,不过非常少。
CCObject类继承自CCCopying类,从CCCopying的名字来看主要是提供对象拷贝的重载,类的定义也证实了这一点。
class CC_DLL CCCopying{public: virtual CCObject* copyWithZone(CCZone* pZone);};cocos2dx的内存管理分为2种,一种是基于引用计数的判断删除对象,一种是每绘制一帧后来进行自动释放对象。另外,cocos2dx的内存管理并不像boost的智能指针那样,在对象离开作用域之后自动删除内存(引用计数),在cocos2dx里边如果要删除对象还需要显示的调用CCObject::release()函数。
第一种内存管理主要是通过CCObject对象的两个函数来进行:retain()和release()。对象调用retain使得引用计数增加1(在创建的时候引用计数初始化为1),release使得对象引用计数减一,但不会立即删除内存,只有对象持有的引用计数等于0的时候才会删除对象。
CCObject::CCObject(void): m_nLuaID(0), m_uReference(1) // when the object is created, the reference count of it is 1, m_uAutoReleaseCount(0){ static unsigned int uObjectCount = 0; m_uID = ++uObjectCount;}
void CCObject::release(void){ CCAssert(m_uReference > 0, "reference count should greater than 0"); --m_uReference; if (m_uReference == 0) { delete this; }}void CCObject::retain(void){ CCAssert(m_uReference > 0, "reference count should greater than 0"); ++m_uReference;}
第二种内存管理初看略显复杂,但是理清楚之后却觉得简单了。还记得在mainloop()函数中,有这么一行代码:
CCPoolManager::sharedPoolManager()->pop();
这一行的作用是release掉当前栈顶内存池里边所有的对象,而且需要注意的是在函数里边只是调用release()函数而已并没有直接delete掉对象。贴一下pop函数的代码以及注释。这里有一个意外的情况,那就是如果在对象池释放对象之前对象被删除了怎么办?会不会造成野指针呢?答案是不会,在CCObject函数里边会检查m_uAutoReleaseCount变量,如果大于0那么就从对象池里边删除掉该对象。
CCObject::~CCObject(void){ // if the object is managed, we should remove it // from pool manager if (m_uAutoReleaseCount > 0) { CCPoolManager::sharedPoolManager()->removeObject(this); } // if the object is referenced by Lua engine, remove it if (m_nLuaID) {
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this); } else { CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine(); if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript) { pEngine->removeScriptObjectByCCObject(this); } }}贴一下CCPoolManager::sharedPoolManager()->pop(); 的代码
void CCPoolManager::pop(){//当前栈顶内存池是否有分配。 if (! m_pCurReleasePool) { return; }//取得栈里边所有内存池数量。 int nCount = m_pReleasePoolStack->count(); //释放掉当前栈顶内存池内存,调用release(),并没有直接delete this。 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;*/}
下面是m_pCurReleasePool->clear()源码及注释
void CCAutoreleasePool::clear(){//内存池对象数组。 if(m_pManagedObjectArray->count() > 0) { //CCAutoreleasePool* pReleasePool;#ifdef _DEBUG int nIndex = m_pManagedObjectArray->count() - 1;#endif CCObject* pObj = NULL;//循环释放掉autoreleasecount标记。 CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj) { if(!pObj) break; --(pObj->m_uAutoReleaseCount); //(*it)->release(); //delete (*it);#ifdef _DEBUG nIndex--;#endif }//释放掉所有保存的对象。调用release() m_pManagedObjectArray->removeAllObjects(); }}看一下m_pManagedObjectArray->removeAllObjects()里边发生了什么。
void CCArray::removeAllObjects(){ ccArrayRemoveAllObjects(data);}
/** Removes all objects from arr */void ccArrayRemoveAllObjects(ccArray *arr){while( arr->num > 0 ) {(arr->arr[--arr->num])->release(); }}
如果需要将对象放到内存池进行自动释放管理只需要调用CCObject::autorelease()就可以了。
至此,cocos2dx的内存管理分析到这了,希望大家能有所收获^_^!
0 0
- coco2dx内存管理(源码版本:cocos2d-x-2.2.3)
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x源码中的内存管理
- 【Cocos2d-x源码分析】 Cocos2d-x内存管理解析
- cocos2d-x 内存管理(3)
- cocos2d-x 内存管理3
- Cocos2d-x 内存管理
- cocos2d-x:内存管理
- Cocos2d-x内存管理
- Cocos2d-x内存管理
- COCOS2D-X内存管理
- Cocos2d-x 内存管理
- cocos2d-x内存管理
- cocos2d-x内存管理
- cocos2d-x 内存管理
- MySql常用命令总结
- Android中利用画图类和线程画出闪烁的心形,送给亲爱的他
- 飞凌OK6410-A学习记录1---宿主机环境配置
- 细说php(三) 运算符与表达式
- 总结
- coco2dx内存管理(源码版本:cocos2d-x-2.2.3)
- 堆排序 原文地址:http://blog.csdn.net/morewindows/article/details/6709644
- hdu 1004 Let the Balloon Rise
- open与fopen区别
- hadoop(HDFS) Commons-logging Log4j
- 【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!
- 2014暑假集训搜索专题
- 2025 查找最大元素
- hdu4585 & BestCoder Round #1 项目管理(vector运用)