關于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。
新聞熱點
疑難解答