前两篇博文我们我们详细分析了cocos2dx的内存管理机制的实现,现在我们在这里简单总结一下:
对于一个对象来说,一般流程:
之前我们分析的时候,知道自动释放池是交给CCPoolManager来管理的,那么现在来看一下这个类:
class CC_DLL CCPoolManager
{
CCArray* m_pReleasePoolStack;
CCAutoreleasePool* m_pCurReleasePool;
CCAutoreleasePool* getCurReleasePool();
public:
CCPoolManager();
~CCPoolManager();
void finalize();
void push();
void pop();
void removeObject(CCObject* pObject);
void addObject(CCObject* pObject);
static CCPoolManager* sharedPoolManager();
static void purgePoolManager();
friend class CCAutoreleasePool;
};
这里我们关注一下addObject方法
void CCPoolManager::addObject(CCObject* pObject)
{
getCurReleasePool()->addObject(pObject);
}CCAutoreleasePool* CCPoolManager::getCurReleasePool()
{
if(!m_pCurReleasePool)
{
push();
}
CCAssert(m_pCurReleasePool, "current auto release pool should not be null");
return m_pCurReleasePool;
}push()方法:
void CCPoolManager::push()
{
CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1
m_pCurReleasePool = pPool;
m_pReleasePoolStack->addObject(pPool); //ref = 2
pPool->release(); //ref = 1
}
然后再看pop方法:
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;*/
}运行程序,发现实际的使用中,push
只被调用了两次!我们知道,通过 addObject 可能会自动调用 push() 一次,但也仅有一次,所以一定是哪里手动调用了 push() 方法,才会出现这种情况,通过查看引擎源码,发现在bool
CCDirector::init(void)中,
有这么一句:
bool CCDirector::init(void)
{
CCLOG("cocos2d: %s", cocos2dVersion());
...
...
m_dOldAnimationInterval = m_dAnimationInterval = 1.0 / kDefaultFPS;
m_pobScenesStack = new CCArray();
m_pobScenesStack->init();
...
...
m_fContentScaleFactor = 1.0f;
...
...
// touchDispatcher
m_pTouchDispatcher = new CCTouchDispatcher();
m_pTouchDispatcher->init();
// KeypadDispatcher
m_pKeypadDispatcher = new CCKeypadDispatcher();
// Accelerometer
m_pAccelerometer = new CCAccelerometer();
// 这里手动调用了 push 方法,而在这之前的初始化过程中,间接的使用了 CCObject 的 autorelease,已经触发过一次 push 方法
CCPoolManager::sharedPoolManager()->push();
return true;
}CCPoolManager::sharedPoolManager()->push(); ,对程序也没任何影响,这样从头到尾,只创建了一个自动释放池,而这里多创建的一个并没有多大的用处。 或者用处不甚明显,因为多创建一个释放池是有其效果的,效果具体体现在哪里,那就是 可以使调用
push() 方法之前的对象,多存活一帧。,因为 pop 方法只对当前释放池做了 clear 释放。
cocos2dx 内存管理(3)---CCPoolManager浅析,布布扣,bubuko.com
cocos2dx 内存管理(3)---CCPoolManager浅析
原文:http://blog.csdn.net/shun_fzll/article/details/22204169