关于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。
新闻热点
疑难解答