当我尝试将CFRunLoopRun();
移回main.m
时,以下代码(很少)失败:
// main.m
int main(int argc, const char * argv[])
{
@autoreleasepool {
Remapper* remapper = [Remapper new];
[remapper run];
// CFRunLoopRun(); // <-- (1) If this is HERE ...
}
return 0;
}
@implementation Remapper
- (void) run {
Intercept* intercept = [Intercept new];
[intercept setup];
CFRunLoopRun(); // (3) but if I put it here, tap_callback now DOES hit.
}
@implementation Intercept
- (void) setup {
[self tapEvents];
[self listen];
}
- (bool) tapEvents {
modifiers = [NSEvent modifierFlags];
if ( ! eventTap )
eventTap = CGEventTapCreate( kCGHIDEventTap, ..., tap_callback, ... );
CGEventTapEnable( eventTap, true );
return CGEventTapIsEnabled( eventTap ); // (4) Note return value is always `true`
}
- (void) listen {
if( ! runLoopSource ) {
runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0 );
CFRunLoopAddSource( CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes );
}
}
CGEventRef tap_callback(...)
{
// (2) This now won't hit!
}
请检查(1)到(4)。
现在,无论CFRunLoopRun()
是在[remapper run]
方法的末尾执行还是在呼叫站点的下一行执行,这可能有什么不同?我看不到任何线程问题的机会。
我只是无法理解。