cocos2dx对象内存管理机制分析
2014-08-06 17:14
375 查看
cocos2dx是通过引用计数的方式管理内存的。这里涉及到4个类:CCObject,CCAutoreleasePool,CCPoolManager和CCDirector;下面介绍这4个类的情况;CCObject是cocos2dx对象的基类(这里指继承于CCObject),里面有一个m_uReference引用计数,它提供了3个主要的方法,如下:
void CCObject::release(void) { CCAssert(m_uReference > 0, "reference count should greater than 0"); --m_uReference;//计数会减1 if (m_uReference == 0) { delete this; } } void CCObject::retain(void) { CCAssert(m_uReference > 0, "reference count should greater than 0"); ++m_uReference; } CCObject* CCObject::autorelease(void) { CCPoolManager::sharedPoolManager()->addObject(this); return this; }
CCAutoreleasePool是自动对象池,新创建的对象会放到这里面管理,它提供了2个主要方法,如下:
4000
ps: 代码中的m_pManagedObjectArray是CCArray类型的对象,用来存储CCObject对象。
void CCAutoreleasePool::addObject(CCObject* pObject) { m_pManagedObjectArray->addObject(pObject); //CCArray::addObject()方法会使对象计数+1,具体可进去看源码 CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1"); ++(pObject->m_uAutoReleaseCount); pObject->release(); // no ref count, in this case autorelease pool added.计数-1 }
void CCAutoreleasePool::clear(){ 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();//removeAllObjects()方法里面会遍历里面的元素,并且调用release()的,这就意味着对象的引用计数-1; }}
CCPoolManager是自动释放池的管理类,是一个singleton,主要内容如下:
CCArray* m_pReleasePoolStack; //用来装CCAutoreleasePool*对象,可能不止一个对象池哦 CCAutoreleasePool* m_pCurReleasePool;//当前使用的对象池
void CCPoolManager::addObject(CCObject* pObject){ getCurReleasePool()->addObject(pObject); //getCurReleasePool()是取到当前使用的对象池;}
void CCPoolManager::pop(){ 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;*/}在看看CCDirector,相关代码如下:
void CCDisplayLinkDirector::mainLoop(void){ if (m_bPurgeDirecotorInNextLoop) { m_bPurgeDirecotorInNextLoop = false; purgeDirector(); } else if (! m_bInvalid) { drawScene(); // release the objects CCPoolManager::sharedPoolManager()->pop(); }}可以看出在 drawScene();之后会去调用CCPoolManager::pop();就是回收对象是在帧的结尾的下面是一个例子,假如MyClass继承CCObject:MyClass*MyClass::create(){MyClass*pRet= newMyClass();pRet->autorelease();returnpRet;}当某处需要创建一个MyClass类型的对象,如下:MyClass*pMyClass =MyClass::create();pMyClass->retain();........那么整个过程是什么样子的呢,往下看当MyClass::create();被调用后,先newMyClass();,此时引用计数为1(看下面代码);
CCObject::CCObject(void): m_nLuaID(0), m_uReference(1) // when the object is created, the reference count of it is 1, m_uAutoReleaseCount(0)
{......},
然后pRet->autorelease();autorelease()就往对象池中加入一个对象:
CCPoolManager::sharedPoolManager()->addObject(this); //实际上这里的引用计数有一个+1再-1的过程,最终计数不变
此时该对象引用计数还是为1;接着pMyClass->retain();后,计数+1变为2,在这帧结束前在CCDirector中调用了
CCPoolManager::sharedPoolManager()->pop(); //这个方法会调用到CCAutoreleasePool::clear(),而clear方法中会遍历对象池中的元素并且都调用CCObject::release()方法,此时该对象的计数-1变为1了,这就是pMyClass->retain()的引用结果(当然如果还在其他地方也retain()的话,计数就不止1了,反正retain()过n次,计数就为n.)当pMyClass不用了,会调用release()方法,此时计数在-1变为0,被delete掉,ok,这个对象生命结束。
但是可能会问,为什么需要autorelease()呢,那放过来看看,如果不用这种机制,当一个对象new后立马被delete了,那么就没法使用这个对象了。使用autorelease()从对象的new开始到帧结束前的release()之间,提供了一个让第三方引用的时机。
相关文章推荐
- 读书笔记 - C++ GUI Qt4 编程(第二版)- Qt 父子对象机制的内存管理
- 从jvm运行机制来分析String对象
- Cocos2dx对象的内存管理3
- iOS中引用计数内存管理机制分析
- cocos2dx内存管理4-CCObject与autorelease 之深入分析
- String对象的内存管理机制
- linux内核分析--浅析内存管理机制
- Cocos2dx对象的内存管理0
- 引用计数的cocos2dx对象内存管理和直接new/delete box2d对象内存管理冲突的解决方法
- 内存管理(4)x86_32地址映射(扩展机制)分析
- C++面向对象特性实现机制的初步分析 Part2
- 深入分析Win7的对象引用跟踪机制
- Linux内存管理之slab机制(释放对象)
- Cocos2dx 对象的内存管理2
- LINUX 2.6.37内存管理 SLAB分析之(3)SLAB对象分配与释放
- C++面向对象特性实现机制的初步分析 Part3
- Linux内存管理之slab机制(分配对象)
- MFC线程独立对象管理机制分析
- cocos2dx 2.1.4 CCNode解析(重点:局部坐标转换机制分析)
- cocos2dx的内存管理机制