我维护一个传统的OSX应用程序而不是调用NSApplicationMain()来处理事件,在主线程上运行一个如下所示的事件循环:
...
do {
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast
inMode: NSDefaultRunLoopMode dequeue:YES];
[self handleEvent:event];
}
} while(event != nil);
...
一切正常,直到我激活应用程序的菜单。菜单处于活动状态后,nextEventMatchingMask将永久阻止。我可以在lldb中看到osx启动另一个模态事件循环(碳?)导致cococa的阻塞:
frame #2: 0x00007fff92748eb4 CoreFoundation`__CFRunLoopServiceMachPort + 212
frame #3: 0x00007fff9274837b CoreFoundation`__CFRunLoopRun + 1371
frame #4: 0x00007fff92747bd8 CoreFoundation`CFRunLoopRunSpecific + 296
frame #5: 0x00007fff8c11c56f HIToolbox`RunCurrentEventLoopInMode + 235
frame #6: 0x00007fff8c11c2ea HIToolbox`ReceiveNextEventCommon + 431
frame #7: 0x00007fff8c17568a HIToolbox`AcquireNextEventInMode + 54
frame #8: 0x00007fff8c172e2b HIToolbox`IsUserStillTracking(MenuSelectData*, unsigned char*) + 173
frame #9: 0x00007fff8c172a41 HIToolbox`TrackMenuCommon(MenuSelectData&, unsigned char*) + 1661
frame #10: 0x00007fff8c1803c1 HIToolbox`MenuSelectCore(MenuData*, Point, double, unsigned int, OpaqueMenuRef**, unsigned short*) + 510
frame #11: 0x00007fff8c1800fe HIToolbox`_HandleMenuSelection2 + 446
frame #12: 0x00007fff8a9a8de0 AppKit`_NSHandleCarbonMenuEvent + 277
frame #13: 0x00007fff8a8dfd0d AppKit`_DPSNextEvent + 1828
frame #14: 0x00007fff8a8def68 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
我能做些什么来阻止这种行为吗? 不幸的是我无法重写应用程序,因此我需要一个快速而肮脏的解决方案来在菜单处于活动状态时运行主线程。