cocos2d-x 3.x内存管理
撰写于 2018-01-30 修改于 2018-01-30 分类 游戏开发
cocos2d-x 3.x中的内存管理很简单:引用计数。凡是继承自Node的类,初始化时,就会自动调用父类(Ref)中autorelease函数,在该函数中,初始化的对象会被加入到内存管理池(PoolManager)中(也就是加到一个vector中)。1
2
3
4
5Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}
节点对象,每retain()一次,该对象的引用计数变量(_referenceCount)就会加1,每release()一次,引用计数变量就减1。在绘制每一帧结束时调用PoolManager::getInstance()->getCurrentPool()->clear(),clear函数会自动清理加入到内存管理池中的对象,只要是对象的引用计数为0就delete掉。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28/*AutoreleasePool::clear() 函数*/
void AutoreleasePool::clear()
{
_isClearing = true;
std::vector<Ref*> releasings;
releasings.swap(_managedObjectArray);
for (const auto &obj : releasings)
{
obj->release();
}
_isClearing = false;
}
/*Ref::release() 函数*/
void Ref::release()
{
CCASSERT(_referenceCount > 0, "reference count should greater than 0");
--_referenceCount;
if (_referenceCount == 0)
{
delete this;
}
}
上面有一个很有意思的STL函数:swap。在使用vector时,如果想清理其中的空间,或者里面有很多无无效数据,怎么办?使用clear()?然而,clear后,内存还是没有释放掉,容器的容量还是一样的,这就要使用神奇的swap函数。先创建一个临时拷贝与原先的vector一致,值得注意的是,此时的拷贝 其容量是尽可能小的符合所需数据的。紧接着将该拷贝与原先的vector进行 交换。好了此时,执行交换后,临时变量会被销毁,内存得到释放。此时的v即为原先的临时拷贝,而交换后的临时拷贝则为容量非常大的vector(不过已经被销毁),大致的过程如下:1
2
3
4
5{
std::vector<int> tmp = ivec;
ivec.swap(tmp);
}
/* 加一对大括号是可以让tmp退出{}的时候自动析构 */