5

我们的 Mac cocos2d 应用程序(http://deepworldgame.com)已经随机抛出“TSMProcessRawKeyCode failed”异常有一段时间了,我想知道是否有人遇到过这个错误或知道如何防止它。

它总是通过 ccKeysDown 或 ccKeysUp 中的 [NSEvent charactersIgnoringModifiers] 调用发生(它也发生在没有修饰符的 [NSEvent characters] 上)。我不认为它与特定的键有关。有时它只发生一次,然后应用程序继续运行(如果捕获到异常),但有时它基本上无限期地锁定键盘输入并继续导致所有未来的按键异常(再次,当这些异常被捕获时)。

不幸的是,我在互联网上几乎没有找到关于这个问题的信息。我确实找到的一个地方是在 Adium 源代码 (https://bitbucket.org/adium/adium/src/6d1f9b903525/Source/AIExceptionController.m) 中,它通过注释捕获了这个异常:

//Ignore various known harmless or unavoidable exceptions (From the system or system hacks) 
...
// [TSMProcessRawKeyCode] May be raised by -[NSEvent charactersIgnoringModifiers]

扔一次确实是无害的,但是当它发生连续发射的时候,这是一个真正的问题——尤其是当你处于全屏模式并且无法使用 cmd-F 逃生时!

因此,如果有人有任何想法或经验,我将不胜感激。这几乎是我们应用程序中仅存的一个超级细菌,我很想将其粉碎。

谢谢!

这是典型的堆栈跟踪(MacManager.m 是我们实现 cocos2d 键盘委托协议的对象):

Crashed Thread:  7  CVDisplayLink

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000

Application Specific Information:
objc[28871]: garbage collection is OFF
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'TSMProcessRawKeyCode failed (-192)'
*** Call stack at first throw:
(
0   CoreFoundation                      0x95b27d87 __raiseError + 231
1   libobjc.A.dylib                     0x9315a149 objc_exception_throw + 155
2   CoreFoundation                      0x95a8f619 +[NSException raise:format:arguments:] + 137
3   CoreFoundation                      0x95a8f589 +[NSException raise:format:] + 57
4   AppKit                              0x9ac01c1f _convertEventRefToString + 300
5   AppKit                              0x9ab23b5e -[NSEvent charactersIgnoringModifiers] + 880
6   Deepworld                           0x0001fd8a -[MacManager ccKeyDown:] + 65
7   CoreFoundation                      0x95a7d091 -[NSObject performSelector:withObject:] + 65
8   Deepworld                           0x0006bc95 -[CCEventDispatcher keyDown:] + 80
9   CoreFoundation                      0x95a7d091 -[NSObject performSelector:withObject:] + 65
10  Deepworld                           0x0006c014 -[CCEventDispatcher dispatchQueuedEvents] + 143
11  Deepworld                           0x0006a9a4 -[CCDirectorDisplayLink getFrameForTime:] + 155
12  Deepworld                           0x0006aaf1 MyDisplayLinkCallback + 40
13  CoreVideo                           0x9b44a5e1 _ZN13CVDisplayLink9performIOEP11CVTimeStamp + 489
14  CoreVideo                           0x9b4494e4 _ZN13CVDisplayLink11runIOThreadEv + 876
15  CoreVideo                           0x9b449161 _ZL13startIOThreadPv + 160
16  libsystem_c.dylib                   0x968a4ed9 _pthread_start + 335
17  libsystem_c.dylib                   0x968a86de thread_start + 34
)
4

1 回答 1

3

我不认为发送事件通常是线程安全的,更不用说从不在 +[NSThread detachNewThreadSelector:toTarget:withObject:] 内创建的线程(使用 Objective-C 运行时创建的线程具有 __NSThread__main__在回溯中)。

我猜你的应用程序是 Deepworld 二进制部分 - 调度事件时,尝试使用 -[NSObject performSelectorOnMainThread:waitUntilDone:] 代替,在主线程上调度事件。

于 2012-11-20T22:46:57.170 回答