C++ 唤醒macOS上的主UI线程后调用wxWidgets?
我在macOS下的GitHub的wxWidgets master下收到“从后台线程调用UI API”错误C++ 唤醒macOS上的主UI线程后调用wxWidgets?,c++,multithreading,macos,wxwidgets,C++,Multithreading,Macos,Wxwidgets,我在macOS下的GitHub的wxWidgets master下收到“从后台线程调用UI API”错误 UI API called from background thread Group file:///DeveloperLibs/wxWidgets-3.1.3/src/osx/cocoa/evtloop.mm: runtime: UI API called from background thread: -[NSApplication postEvent:atStart:] must be
UI API called from background thread Group
file:///DeveloperLibs/wxWidgets-3.1.3/src/osx/cocoa/evtloop.mm: runtime: UI API called from background thread: -[NSApplication postEvent:atStart:] must be used from main thread only
#0 0x00000001004e5908 in wxGUIEventLoop::WakeUp() at /DeveloperLibs/wxWidgets-3.1.3/src/osx/cocoa/evtloop.mm:390
#1 0x00000001004651fd in wxApp::WakeUpIdle() at /DeveloperLibs/wxWidgets-3.1.3/src/osx/carbon/app.cpp:439
#2 0x00000001001d0cf7 in wxWakeUpIdle() at /DeveloperLibs/wxWidgets-3.1.3/src/common/appbase.cpp:1108
#3 0x00000001003a6a03 in wxEvtHandler::QueueEvent(wxEvent*) at /DeveloperLibs/wxWidgets-3.1.3/src/common/event.cpp:1318
#4 0x000000010017a09c in void wxEvtHandler::CallAfter<myPanel::Finish()::$_1>(myPanel::Finish()::$_1 const&) at /DeveloperLibs/wxWidgets-3.1.3/include/wx/event.h:3668
#5 0x0000000100179fba in myPanel::Finish() at /Volumes/Macintosh HD04/Users/rich/Projects/thing/myPanel.cpp:88
问题不在于lambda中的代码,而是实际的CallAfter调用,因为它调用了wxWakeUpIdle()
,然后在wxApp::WakeUpIdle()
中结束,最后在wxGUIEventLoop::WakeUp()
中调用[NSApp postEvent:event atStart:FALSE]代码>
通过这种方式,我的后台线程正在唤醒UI线程。wxEvtHandler::CallAfter
的文档说明:
请注意,从其他非GUI线程使用CallAfter()是安全的,但该方法将始终在主GUI线程上下文中调用
这里似乎不是这样?我做错了什么
编辑:顺便说一句,这是在macOS Catalina下。在macOS Sierra和wxWidgets 3.1.3下,我没有收到关于相同代码的运行时警告。evtloop.mm代码相同,但在此旧版macOS下不会生成警告 恐怕wx内部的CallAfter()
的实现需要修改,但是如果我们不能再从工作线程调用[NSApp postEvent:atStart://code>,我不知道我们应该如何将事件从它们传递到主线程。是的,警告似乎是错误的。通过快速搜索,glfw报告了相同的问题。并声明wxWidgets正在做的事情是可以的,所以我现在将忽略警告,希望应用商店提交成功。我没有意识到这只是一个警告,我认为这是一个(致命的)错误。如果它只是一个警告,我认为它确实可以被忽略,至少现在是这样……当您在调试器下运行它时,它是Xcode中报告的“运行时问题”。我不确定这些物体的重力有多大。一如既往地谢谢你。
void myPanel::Finish()
{
this->GetEventHandler()->CallAfter([this]()
{
stopButton->Disable();
GoToResultsPanel();
});
}