I encounter a problem when I develop my game with cocos2d-x. After digging the issue for a while, I’m basically sure that this is a bug in cocos2d-x.
Bug description:
This is the function to add an observer,
void CCNotificationCenter::addObserver(CCObject *target, SEL_CallFuncO selector, const char *name, CCObject *obj);
The last parameter means which object the observer cares about. It shouldn’t be just ignored before post notification:
void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
CCObject* obj = NULL;
CCARRAY_FOREACH(m_observers, obj)
{
CCNotificationObserver* observer = (CCNotificationObserver*) obj;
if (!observer)
continue;
if (!strcmp(name,observer->getName()))
observer->performSelector(object);
}
}
The highlighted code is where the bug exists. It only checks the notification name, without the object that the observer cares about. There are 2 reasons:
# If we don’t check the object pointer, he observer~~>object doesn’t matter any more. There’s no different that we pass an object pointer or NULL as the last parameter when calling addObserver. It’s not it’s supposed to do. This also shows incomplete behavior comparing to NSNotificationCenter in Cocoa.
# There is a serious problem as a result. Consider more than one observer listens the same event of the same notification name. Each observer would receive the notification even if the event comes from an object they explicitly doesn’t care about. In this case, the postNotification would be a mess and take us a lot of time to debug!
The fix is very simple, just check the object before post notification:
<pre>
if ) && == object))
observer~~>performSelector(object);