对于某些击键,performKeyEquivalent被调用两次

时间:2013-08-23 13:35:01

标签: cocoa

按“Command +”会导致两个-performKeyEquivalent调用。这是第一次调用的堆栈跟踪片段:

1   AppKit                              0x00007fff903da2f9 -[NSView _performKeyEquivalent:conditionally:] + 41
2   AppKit                              0x00007fff903da442 -[NSView performKeyEquivalent:] + 166
3   AppKit                              0x00007fff903da2f9 -[NSView _performKeyEquivalent:conditionally:] + 41
4   AppKit                              0x00007fff903da259 -[NSWindow performKeyEquivalent:] + 64
5   AppKit                              0x00007fff903da044 -[NSApplication _handleKeyEquivalent:] + 462
6   AppKit                              0x00007fff90297173 -[NSApplication sendEvent:] + 4480

第二次电话:

1   AppKit                              0x00007fff903da2f9 -[NSView _performKeyEquivalent:conditionally:] + 41
2   AppKit                              0x00007fff903da442 -[NSView performKeyEquivalent:] + 166
3   AppKit                              0x00007fff903da2f9 -[NSView _performKeyEquivalent:conditionally:] + 41
4   AppKit                              0x00007fff903da259 -[NSWindow performKeyEquivalent:] + 64
5   AppKit                              0x00007fff903da044 -[NSApplication _handleKeyEquivalent:] + 462
6   AppKit                              0x00007fff900e3927 -[NSApplication _handleSpecialAlternateKeyEquivalent:] + 656
7   AppKit                              0x00007fff9029718e -[NSApplication sendEvent:] + 4507

如您所见,第二个-performKeyEquivalent调用由 - [NSApplication _handleSpecialAlternateKeyEquivalent:]启动。那么,有人能告诉我“Command +”击键有什么特别之处吗?它保证不是一个,而是两个-performKeyEquivalent调用,以及如何过滤掉第二个调用?

1 个答案:

答案 0 :(得分:1)

最可能的原因是第一次调用返回NO,因此AppKit会再次尝试稍微不同的事件。你是否压倒performKeyEquivalent:?你是第一次回归NO吗?


来自Cocoa Event Handling Guide: Handling Key Events的说明:

  

不鼓励NSWindow子类覆盖performKeyEquivalent:。

     

注意:从OS X v10.5开始,如果无法识别等效的密钥,NSWindow会将其作为NSKeyDown事件发送给第一个响应者。此行为启用带有命令键修饰符的自定义键绑定条目。此外,NSApplication通过performKeyEquivalent将密钥窗口发送到密钥窗口:在通过响应程序链将其作为NSKeyDown事件发送之前。此行为允许更可靠地使用Control-key事件作为菜单键等效。