cocos2dx EventListenerCustom 和NotificationCenter的优缺点
来源:互联网 发布:出国留学值得吗 知乎 编辑:程序博客网 时间:2024/05/24 04:17
(本人总结,如有不对,请多多指正)
自从cocos2dx 3.x后,NotificationCenter就标记为废弃了,而是用EventListenerCustom代替
NotificationCenter 实现很简单,里面有着数组NotificationObserver
当你注册了一个消息的同时,也注册了消息所响应的函数,这些包含在NotificationObserver类中,当有消息发出时,NotificationCenter就循环NotificationObserver
,如果名称对应,结点对应,就直接调用函数,代码如下
CCARRAY_FOREACH(ObserversCopy, obj) { NotificationObserver* observer = static_cast<NotificationObserver*>(obj); if (!observer) continue; if (observer->getName() == name && (observer->getSender() == sender || observer->getSender() == nullptr || sender == nullptr)) { if (0 == observer->getHandler()) { observer->performSelector(sender); } } }
而EventListenerCustom就不同,和EventListenerTouchOneByOne等相同,它们内部是通过EventDispatcher发送和响应消息的。EventDispatcher是单例类,保存在Director中,其他Node保存的只是它的引用。通过EventListenerCuston发送消息有一个弊端,就是消息有可能不能被接收,即当你发送消息而对应的函数可能没有被调用。
看Node中的onEnter代码
void Node::onEnter(){#if CC_ENABLE_SCRIPT_BINDING if (_scriptType == kScriptTypeJavascript) { if (ScriptEngineManager::sendNodeEventToJS(this, kNodeOnEnter)) return; }#endif if (_onEnterCallback) _onEnterCallback(); if (_componentContainer && !_componentContainer->isEmpty()) { _componentContainer->onEnter(); } _isTransitionFinished = false; for( const auto &child: _children) child->onEnter(); this->resume();//重点是这句 _running = true; #if CC_ENABLE_SCRIPT_BINDING if (_scriptType == kScriptTypeLua) { ScriptEngineManager::sendNodeEventToLua(this, kNodeOnEnter); }#endif}
接下来看看this->resume()做了什么
void Node::resume(){ _scheduler->resumeTarget(this); _actionManager->resumeTarget(this); _eventDispatcher->resumeEventListenersForTarget(this);//重点}一般情况下 Node::onEnter()是在addChild中是被调用的,而场景类的onEnter()是在切换场景是被调用的,如下
void Director::setNextScene(){ bool runningIsTransition = dynamic_cast<TransitionScene*>(_runningScene) != nullptr; bool newIsTransition = dynamic_cast<TransitionScene*>(_nextScene) != nullptr; // If it is not a transition, call onExit/cleanup if (! newIsTransition) { if (_runningScene) { _runningScene->onExitTransitionDidStart(); _runningScene->onExit(); } // issue #709. the root node (scene) should receive the cleanup message too // otherwise it might be leaked. if (_sendCleanupToScene && _runningScene) { _runningScene->cleanup(); } } if (_runningScene) { _runningScene->release(); } _runningScene = _nextScene; _nextScene->retain(); _nextScene = nullptr; if ((! runningIsTransition) && _runningScene) { _runningScene->onEnter();//重点 _runningScene->onEnterTransitionDidFinish(); }}
也就是说,你在层或者场景的init里是无法通过EventListenerCustom发送事件的。因为当时的事件是暂停的
if (sceneGraphPriorityListeners) { if (!shouldStopPropagation) { // priority == 0, scene graph priority for (auto& l : *sceneGraphPriorityListeners) { if (l->isEnabled() && !l->isPaused() && l->isRegistered() && onEvent(l))//重点 { shouldStopPropagation = true; break; } } } }
所以个人认为,NotificationCenter和EventListenerCustom并没有孰优孰劣,看个人需求
下面总结相同点和不同点
相同点:都能发送消息从而使对应的函数被调用
不同点 NotificaCenter需要显式地移除,EventListenerCustom只有在场景跑起来后才可以响应
1 0
- cocos2dx EventListenerCustom 和NotificationCenter的优缺点
- Cocos2dx NotificationCenter(广播或通告)的使用方法
- cocos2dx EventListenerCustom类控制事件的分发 处理不同层之间的事件传递以及自定义用户数据
- NotificationCenter的基本使用
- NotificationCenter
- NotificationCenter
- NotificationCenter
- cocos2dx[3.2](21)——观察者模式NotificationCenter
- Swift-通知中心(NotificationCenter)的使用
- cpld和fpga的优缺点
- table和div的优缺点
- struts1和struts2的优缺点
- LinkedList和ArrayList的优缺点
- JavaScript和jQuery的优缺点
- Irrlicht和Ogre 的优缺点
- SSH的优缺点和原理
- DTD和schema的优缺点
- dwr和query的优缺点
- PHPStorm 常用 设置配置 和快捷键大全 Win/Mac
- 5-1 求阶乘factorial
- linux下如何安装软件?——linux应用软件安装包类型及安装介绍
- Ubuntu 16.04 LTS 一直不可更新,已可使用三种升级方法解析(一定有适合的方法)
- Error:Connection timed out: connect. If you are behind an HTTP proxy, please configure the proxy set
- cocos2dx EventListenerCustom 和NotificationCenter的优缺点
- 简单算法
- re命名捕获
- 作业8 Problem G: 编写函数:Swap (I) (Append Code)
- 程序员的书籍资源
- vi编辑器的配置
- 离线web缓存
- Android Studio Error running app IDE or the Gradle plugin to the latest version
- hdu1099(map用法)