LUA_API int setNodePRI(lua_State * L) { TouchSprite * del = static_cast<TouchSprite*>(lua_touserdata(L, 1)); jassert(del && del->getParent()); int pri = lua_tointeger(L, 2); JLayer * layer = static_cast<JLayer*>(del->getParent()); jassert(layer); CCTouchDispatcher * dispatcher = CCDirector::sharedDirector()->getTouchDispatcher(); //尼玛莫名奇妙呀 jassert(dispatcher->findHandler(del)); dispatcher->setPriority(LAYER_MAX-layer->getLayerOrder().y + pri, del); return 0; }
这段代码跑过无数次了,一直都很正常,然而今天这里却发生一个异常。
CCDirector::sharedDirector()->getTouchDispatcher()找不到del的handler,在jassert(dispatcher->findHandler(del)); 处发生异常。
这实在是奇怪,前面刚刚注册了del的touch回调的。代码一切都很正常,为什么会出现异常呢?
没办法,只好一头扎进cocos2d-x的源码里面寻找真相了。
addTargetedDelegate函数在添加pDelegate指针时会有一个判定:
if (! m_bLocked) { forceAddHandler(pHandler, m_pTargetedHandlers); } else { ...m_pHandlersToAdd->addObject(pHandler);
调试发现代码走的是第二条路线,怎么,上锁了?
唯一能上锁的地方位于:
void CCTouchDispatcher::touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex){ CCAssert(uIndex >= 0 && uIndex < 4, ""); CCSet *pMutableTouches; m_bLocked = true;
这才恍然大悟,原来我是在Layer的touch事件中添加一个精灵,并为该精灵注册touch回调,此时CCTouchDispatcher处于上锁状态,因此注册不上。
那该如何处理呢?
只能通过别的方式绕过去了。修改cocos2d-x的源代码并不是好事,自己的逻辑还是写在自己的代码里面吧:)