cocos2d-x CCNotificationCenter一个优化想法

 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);
}

 本文原创,转载请注明原文地址

原文地址:https://www.cnblogs.com/kaisne/p/3474821.html