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 有任何其他问题,你应该跳出循环。
我创建了一个这样的 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 有任何其他问题,你应该跳出循环。