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

时间:2015-10-19 08:09:24

标签: objective-c core-foundation

我创建了一个像这样的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,这意味着没有源处于该模式。但我清楚地对共同模式选项CFRunLoopAddSource做了kCFRunLoopRunFinished. The run loop mode mode has no sources or timers.。有谁知道什么?这是非主线程。

1 个答案:

答案 0 :(得分:1)

您无法在kCFRunLoopCommonModes中运行运行循环。 CFRunLoopRunInMode()的文档中明确说明了这一点。

kCFRunLoopCommonModes是一种虚拟模式。它基本上是一组其他模式。它只能在向运行循环添加(或删除)源时使用,以便在运行循环以集合中的任何模式运行时监视此源。但是当你运行一个运行循环时,你必须以特定的实模式运行它,而不是这个代表一组其他模式的虚拟模式。

我建议,当您在私有线程上工作并且只想监视私有源时,可以将源添加到自定义模式并在该模式下运行运行循环。自定义模式只是具有唯一值的字符串。例如,像&#34; com.yourcompany.yourproject.yourmodespurpose&#34;。使用自定义模式可确保运行循环不会发生任何意外情况,例如触发框架添加的源。

您不得发布aLoop。没有的功能&#34;创建&#34;或&#34;复制&#34;在他们的名下不给你所有权。

您需要循环调用CFRunLoopRunInMode(),因为它会在每次处理来自您的来源(kCFRunLoopRunHandledSource == 4)的事件时返回,或者达到超时(kCFRunLoopRunTimedOut == 3)。如果它返回任何其他内容,你应该打破循环。