在执行后台任务时与Objective-C中的GUI交互

Interact with GUI in Objective-C while performing background task

本文关键字:中的 GUI 交互 Objective-C 执行 后台任务      更新时间:2023-10-16

我创建了一个捆绑包,作为Cocoa应用程序的插件,我只能通过C/C++SDK与之接口。根据SDK,我的插件执行一个函数,通过引用设置结果数据对象并返回结果错误代码。

由于我团队中的开发人员在Java方面更有经验,我们使用管道在C/C++和Java之间架起了一座桥梁。因此,当我调用SDK函数时,它会通过管道向Java发送一条消息,指示它执行Java方法。Java方法向C/C++SDK发送一个或多个回调消息,该消息将最终设置结果数据对象并返回原始SDK函数的结果错误代码。

除非我的代码需要生成一个Java GUI(例如,一个RGB值将通过C/C++SDK存储的颜色选择器),否则这种机制运行得很好。我希望我的Java GUI显示类似于纯Cocoa应用程序中模式子窗口的行为。换句话说,当我与主窗口的GUI交互时,我不希望它阻塞(旋转沙滩球),同时保持Java GUI在Cocoa GUI之上。

到目前为止,我所尝试的是创建一个后台线程,将我的方法调用消息发送到Java。在Java方法生成GUI之前,我会通过管道向C/C++发送一条特殊消息。当C/C++接收到该消息时,我注册一个窗口观察器,然后使用Objective-C++使用消息端口源(仍在后台线程上)启动运行循环。

我的想法是,由于我的管道读取是阻塞的,在Java GUI被处理之前,我不需要读取任何其他内容,所以我应该在后台线程中启动一个运行循环,希望这能让我与Cocoa GUI交互,从而引起一个通知,我的观察者会识别Java GUI,并将其带回Cocoa GUI前面。当我处理Java GUI时,它将使用JNI向C/C++发送一个远程消息端口请求,并停止运行循环。

取而代之的是主GUI块,直到我处理掉Java GUI,然后执行上面描述的代码。我想这是因为我需要主线程等待结果,以便它可以将结果返回给C/C++函数。我使用的机制是std::async,它返回std::future,我调用get()。我知道我对get()的调用是我出错的地方,但我不知道如何等待后台线程完成。

如果有帮助的话,我很乐意提供代码片段,但我想知道是否有人能理解我所描述的内容,并提供一些可能帮助我走上正轨的一般建议。

我能够解决阻塞问题,方法是在Cocoa进程的主窗口上创建一个透明窗口,并执行我的操作,告诉Java进程在后台线程中生成一个GUI。

[[NSApplication sharedApplication] runModalForWindow:transparentWindow]