CFRunLoopRunInMode 正在退出,代码为 1,就好像没有添加任何内容一样

CFRunLoopRunInMode is exiting with code 1, as if nothing was added

我创建了一个这样的 CGEventTap:

GetCurrentProcess(psn);

var mask =  1 << kCGEventLeftMouseDown | // CGEventMaskBit(kCGEventLeftMouseDown)
            1 << kCGEventLeftMouseUp | 
            1 << kCGEventRightMouseDown |
            1 << kCGEventRightMouseUp |
            1 << kCGEventOtherMouseDown |
            1 << kCGEventOtherMouseUp |
            1 << kCGEventScrollWheel;

mouseEventTap = CGEventTapCreateForPSN(&psn, kCGHeadInsertEventTap, kCGEventTapOptionDefault, mask, null);

if (!mouseEventTap.isNull()) {
      aRLS = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mouseEventTap, 0);
      CFRelease(mouseEventTap);

      if (!aRLS.isNull()) {
            aLoop = CFRunLoopGetCurrent();

            CFRunLoopAddSource(aLoop, aRLS, kCFRunLoopCommonModes);

            CFRelease(aRLS);
            CFRelease(aLoop);

            rez = CFRunLoopRunInMode(ostypes.CONST.kCFRunLoopCommonModes, 10, false); // figure out how to make this run indefinitely
            // rez is 1 :(

      }

}

我的 CFRunLoopRun 立即退出,而不是 运行 10 秒。它说代码是 1,这意味着没有源处于该模式。但是我显然对公共模式选项kCFRunLoopRunFinished. The run loop mode mode has no sources or timers.做了一个CFRunLoopAddSource。有人知道怎么回事吗?这是在非主线程上。

您不能在 kCFRunLoopCommonModes 中 运行 运行 循环。 CFRunLoopRunInMode().

的文档中明确说明了这一点

kCFRunLoopCommonModes是虚拟模式。它基本上是一组其他模式。它只能在将源添加(或删除)到 运行 循环以说 "monitor this source when the run loop is run in any of the modes in the set" 时使用。但是当你 运行 一个 运行 循环时,你必须 运行 它处于特定的实模式,而不是代表一组其他模式的虚拟模式。

我建议,当您在私有线程上工作并且只想监视私有源时,您将源添加到自定义模式,然后 运行 运行 循环模式。自定义模式只是一个具有唯一值的字符串。例如,"com.yourcompany.yourproject.yourmodespurpose"。使用自定义模式确保 运行 循环永远不会做任何意外的事情,比如触发框架添加的源。

你不能释放aLoop。名称中没有 "Create" 或 "Copy" 的函数不会授予您所有权。

您将需要围绕对 CFRunLoopRunInMode() 的调用进行循环,因为它会 return 每次处理来自源 (kCFRunLoopRunHandledSource == 4) 的事件或达到超时(kCFRunLoopRunTimedOut == 3)。如果它 return 有任何其他问题,你应该跳出循环。