【发布时间】:2021-03-06 02:34:26
【问题描述】:
与this other question 相关:我需要收集有关macOS 上当前活动应用程序的信息。
链接的 QA 答案提供了一种机制,可在活动应用程序更改时收到警报(事件),但在单独的线程上运行时会崩溃:
FocusDetector::AppFocus focus;
focus.run();
//std::thread threadListener(&FocusDetector::AppFocus::run, &focus); //Does not works
//if (threadListener.joinable())
//{
// threadListener.join();
//}
.
*** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /xxxxxxx/NSUndoManager.m:363
2020-11-24 08:54:41.758 focus_detection[81935:18248374] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff3006cb57 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff68eb35bf objc_exception_throw + 48
2 CoreFoundation 0x00007fff30095d08 +[NSException raise:format:arguments:] + 88
3 Foundation 0x00007fff32787e9d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4 Foundation 0x00007fff326c45ee +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 440
5 AppKit 0x00007fff2d25165c -[NSApplication run] + 864
6 focus_detection 0x0000000104b1a010 _ZN13FocusDetector8AppFocus3runEv + 128
7 focus_detection 0x0000000104b19547 _ZNSt3__1L8__invokeIMN13FocusDetector8AppFocusEFvvEPS2_JEvEEDTcldsdeclsr3std3__1E7forwardIT0_Efp0_Efp_spclsr3std3__1E7forwardIT1_Efp1_EEEOT_OS6_DpOS7_ + 119
8 focus_detection 0x0000000104b1944e _ZNSt3__1L16__thread_executeINS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEMN13FocusDetector8AppFocusEFvvEJPS7_EJLm2EEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE + 62
9 focus_detection 0x0000000104b18c66 _ZNSt3__114__thread_proxyINS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEMN13FocusDetector8AppFocusEFvvEPS8_EEEEEPvSD_ + 118
10 libsystem_pthread.dylib 0x00007fff6a260109 _pthread_start + 148
11 libsystem_pthread.dylib 0x00007fff6a25bb8b thread_start + 15
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6
这显然与NSApplication有关,文档说明:
每个应用都使用一个 NSApplication 实例来控制主事件循环
因此,我正在寻找另一种监听事件的方法,它不限于主事件循环(或主线程。
直观地说,应该可以在单独的线程中获取有关当前应用程序焦点的信息。
我不知道如何解决这个问题,抱歉没有提供太多研究。我确实在互联网上研究了“NSNotification不在主线程中”和其他类似的句子,但没有成功。
问题:
如何在主线程外监听activeAppDidChangeNSNotification?
【问题讨论】:
-
好吧,在 c++ 类中包装通知观察器的使用不会改变它们发布的线程。
-
正确,但是一旦我取消注释创建线程并在内部调用 AppFocus::run 的行,它就会崩溃,“只能在主线程上安全调用”,所以我猜它是与在线程内运行 NSApplication::run 有关。
-
+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.这是一个远离 NSWorkspaceDidActivateApplicationNotification 的问题。你想做什么,你的目标是什么?在不同的线程中请求另一个应用程序状态需要注意其他应用程序的主线程消失。 -
我的目标是什么?:一个后台应用程序,需要检测哪个应用程序(PID)有焦点。主线程不可用(这意味着重构太多,可能有数十万行)。我可以创建一个侦听器线程,但它不会是主线程。链接的答案是一个完整的示例,到目前为止创建线程的行已被注释。
-
你知道我的例子就是这样做的..
pid_t pid = ((NSRunningApplication *)note.userInfo[NSWorkspaceApplicationKey]).processIdentifier;,这个例子有一个单独的线程和一个线程管理器。
标签: objective-c multithreading macos events nsworkspace