Director::setNextScene解析

bool newIsTransition = dynamic_cast(_nextScene) != nullptr;

如果这个newIsTransition不是一个TransitionScene的话我们就调用_runningScene的onExit和onExiteTransitionDidStart2个函数,当前_runningScene退出了。

接下来_sendCleanupToScene这个变量实在PopScene和replaceScene时候被设置成ture的,所以当调用replasceScene时候会调用_runningScene->cleanup();这个cleanup是Node的方法。

下面说说cleanup方法:

for( const auto& child : _children )  child->cleanup();

他会递归的调用所有子节点的cleanup()方法。也就是当前层的所有子节点都会被cleanup一次。

cleanup开始时有个2个调用:下面2个方法都是Node成员方法

this->stopAllActions();

this->unscheduleAllCallbacks();

在调用stopAllactions时,由_actionManager->removeAllActionsFromTarget(this);

此时他会在Action中找到与当前this相关的Action,然后调用deleteHashElement方法。在deleteHashElement方法中会调用与此actionElement绑定的Node->release(),这个Node就是上面的this指针。然后free掉这个element。

到此可以说明个问题:那就是cocos2d中的Action是由自身执行这个action的Node对象自身管理的,在这个Node中有成员变量_actionManager它负责Action的管理。当切换场景的时候,由上面指出的只要这个Node在running中它就会被调用cleanup。

形如这样:auto node = Sprite::create(""); node->runAction( Action );时,node的refCount会+1,但是这个refCount在replaceScene时,会被自身的_actionManager查询到,并且会调用node->release()一次,所以动作引发的refCount++不用我们自己处理,引擎是通过刚才分析去使refCount--的。

继续说setNexScene下面做的事情:

接下来就是要处理新场景。

_runningScene = _nextScene; 

_runningScene->retain();

_runningScene->onEnter(); 

_runningScene->onEnterTransitionDidFinish();

到此整个setNextScene解析完毕

总结:setNextScene方法中最重要的就是_sendCleanupToScene这个变量控制的cleanup了。由cleanup清理掉所有场景及场景所有子节点。重要的就是使得引擎内部维护的Node的refCount--工作。

你可能感兴趣的:(Director::setNextScene解析)