1 void CCNotificationCenter::postNotification(const char *name, CCObject *object) 2 { 3 CCArray* ObserversCopy = CCArray::createWithCapacity(m_observers->count()); 4 ObserversCopy->addObjectsFromArray(m_observers); 5 CCObject* obj = NULL; 6 CCARRAY_FOREACH(ObserversCopy, obj) 7 { 8 CCNotificationObserver* observer = (CCNotificationObserver*) obj; 9 if (!observer) 10 continue; 11 12 if (!strcmp(name,observer->getName()) && (observer->getObject() == object || observer->getObject() == NULL || object == NULL)) 13 observer->performSelector(object); 14 } 15 16 if (m_scriptHandler) 17 { 18 CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine(); 19 engine->executeNotificationEvent(this, name); 20 } 21 }
从上面代码中可以看到发送消息的时候是遍历所有的Observer,这样对于频繁发送消息的时候,非常低效率。我的想法是修改CCNotificationCenter的 CCArray *m_observers 为 CCDictionary * m_observers(key为消息,value是一个CCSet *),因为CCNotificationCenter使用过程中更多是面向消息。
修改后的代码如下:
// // internal functions // bool CCNotificationCenter::observerExisted(CCObject *target,const char *name) { CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name); if (mgsObservers) { for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){ CCNotificationObserver* observer = (CCNotificationObserver*) (* iter); if (observer->getTarget() == target) return true; } } return false; } // // observer functions // void CCNotificationCenter::addObserver(CCObject *target, SEL_CallFuncO selector, const char *name, CCObject *obj) { if (this->observerExisted(target, name)) return; CCNotificationObserver *observer = new CCNotificationObserver(target, selector, name, obj); observer->autorelease(); CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name); if(!mgsObservers){ mgsObservers = CCSet::create(); m_observersDic->setObject(mgsObservers, name); } mgsObservers->addObject(observer); } void CCNotificationCenter::removeObserver(CCObject *target,const char *name) { CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name); if(mgsObservers){ for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){ CCNotificationObserver* observer = (CCNotificationObserver*) (* iter); if (observer->getTarget() == target){ mgsObservers->removeObject(observer); return; } } } } int CCNotificationCenter::removeAllObservers(CCObject *target) { int removeCount = 0; CCDictElement* pElement = NULL; CCDICT_FOREACH(m_observersDic, pElement) { CCSet* mgsObservers = (CCSet*)pElement->getObject(); for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end();){ CCNotificationObserver* observer = (CCNotificationObserver*) (* iter); if (observer->getTarget() == target){ mgsObservers->removeObject(observer); removeCount ++ ; }else{ iter++ } } } return removeCount; } void CCNotificationCenter::postNotification(const char *name, CCObject *object) { CCSet* mgsObservers = (CCSet*)m_observersDic->objectForKey(name); if(mgsObservers){ for (CCSetIterator iter = mgsObservers->begin(); iter != mgsObservers->end(); iter++ ){ CCNotificationObserver* observer = (CCNotificationObserver*) (* iter); if ((observer->getObject() == object || observer->getObject() == NULL || object == NULL)){ observer->performSelector(object); } } } if (m_scriptHandler) { CCScriptEngineProtocol* engine = CCScriptEngineManager::sharedManager()->getScriptEngine(); engine->executeNotificationEvent(this, name); } } void CCNotificationCenter::postNotification(const char *name) { this->postNotification(name,NULL); }
本文原创,转载请注明原文地址!