cocos2d-x使用引用计数和自动释放池的内存管理技术。
(一)引用计数的道理很简单,就是在对象的内部增加一个计数器,当其外部引用增加时,计数就加一,当外部引用消失时,计数器就减一。
在cocos2d-x中,任何对象都可以使用引用计数的方式,主要是因为CCObject提供了引用计数功能。在对象创建之初,计时器为一,当retain时,就会加一,relese时就会减一,当为零时,就会释放对象。
引用计数主要的问题就是,如果发生对象被删除,但是引用还存在,程序就会出现访问错误。如果对象引用不在,而没有被删除,则会变成内存泄露的对象。为了不出现上述问题,要注意以下几点:
1,有开始就有结束,创建一个对象的时候,必须要释放它,创建对象的方式通常为new 和copy,无论是哪一种,当对象不再使用后,都需要release释放。
2,有引用就要有释放,调用retain时,引用加一,不再引用时,调用release函数
3,参数传递需要更替引用,在函数内有需要引用对象,则此时首先需要释放旧的引用对象,然后增加新的引用对象。
(二)通过调用函数autorelease来将对象放到自动释放池中进行管理。
CCObject *object = new CCObject;
//将对象放入自动释放池
obj->autorelease();
实现原理:通过类CCPoolManger来管理自动释放池中的对象,当场景销毁,程序退出,渲染周期结束,内存管理就会遍历其所管理的每一个对象,逐个调用对象的释放函数进行释放。
CCObject * CCObject::autorelease(void)
{
//将对象添加到释放池中
CCPoolManager::sharedPoolManager()->addObject(this);
//设置自动释放的属性
m_bManged= true;
return this;
}
自动释放对象
void CCAutoreleasePool::clear()
{
if(m_pManagedObjectArray->count() > 0)
{
//调试信息
#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();
}
}