<常见错误>"Delegate already added to touch dispatcher."的解决方案
错误提示: *** Assertion failure in -[CCTouchDispatcher forceAddHandler:array:] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Delegate already added to touch dispatcher.'
分析: 在触摸屏幕时,会调用下面的伪代码,其中idx是一种枚举类型,表示Touchbegin、TouchEnd等等 1 -(void) touches:(NSSet*)touches withEvent:(UIEvent*)event withTouchType:(unsigned int)idx{ 2 locked = YES; 3 触摸消息的转发... 4 locked = NO; 5 // 先删除代理对象,再增加代理对象 6 if(ToRemove){ 7 remove from NeedToRemoved 8 } 9 if(ToAdd){ 10 add from NeedToAdd 11 } 12 } 比如你在ccTouchesBegan:withEvent: 中调用[self setIsTouchEnabled:NO]或者[self setIsTouchEnabled:YES]; 由于正在触摸,locked = YES; 因此需要添加的handler和需要移除的的handler分别存储在两个不同的可变数组中,并非马上添加或者删除。 这两个CCTouchDispatcher中的数组分别是NSMutableArray*handlersToAdd; NSMutableArray*handlersToRemove; 当消息分发完毕后,会从上述伪代码的第6行开始继续执行,可以看出,会先删除handlersToRemove数组中的元素,后增加handlersToAdd中的元素。 1 - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 2 [self setIsTouchEnabled:YES]; 3 [self setIsTouchEnabled:NO]; 4 } 正因为如此,如果你在同一次ccTouchesBegan中先调用[self setIsTouchEnabled:YES],再调用[self setIsTouchEnabled:NO],你本以为这与“只调用[self setIsTouchEnabled:NO]”一样,其实不然。执行完后也许还是[self setIsTouchEnabled:YES];的效果,这和isTouchEnabled_又有关系,具体问题具体分析了。
强烈建议参看:全面剖析Cocos2d游戏触摸机制,看完自然都熟悉了。 |