关于cocos2dx内存管理的记录。
//创建一个精灵
auto sprite = Sprite::create("HelloWorld.png");
//此时的引用计数为1
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize / 2) + origin);
sprite->setTag(123);
// add the sprite as a child to this layer
this->addChild(sprite);
//addchild 以后此时的引用计数为2
//三帧以后释放精灵
this->scheduleOnce([this](float dt) {
//释放前,引用计数变成了1
/*
为什么变成了1,明明创建的时候是2.
这个问题,我纠结了一天。后来,明白了。
*/
this->removeChildByTag(123);
//释放后,引用计数,就没了。
}, 3,"update");
为什么变成了1呢?
void Director::mainLoop()
{
if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
purgeDirector();
}
else if (_restartDirectorInNextLoop)
{
_restartDirectorInNextLoop = false;
restartDirector();
}
else if (! _invalid)
{
drawScene();
// release the objects
//这里在每一帧的末尾会clear 继续点开。
PoolManager::getInstance()->getCurrentPool()->clear();
}
}
void AutoreleasePool::clear()
{
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = true;
#endif
std::vector<Ref*> releasings;
//清空自动回收池
releasings.swap(_managedObjectArray);
for (const auto &obj : releasings)
{
//这里进行了释放过程,也就是引用计数减1
obj->release();
}
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = false;
#endif
}
这一帧已经清空了自动回收池,下一帧就不会 再for循环了。所以精灵的引用计数,一直保持1,直到调用remove,remove里面有release 又会减1,就会被释放。
小插曲:
cocos2dx 所有的自动回收必须依托ref进行。
ccnode 就是一个节点。addchild就是往这个节点上添加子节点,如果ccnode被释放,则子节点也会被释放。
所以 virtual ~Node(); 析构函数,要加virtual。