阻塞主线程的状态项(NSMenu 阻止 NSSpeechRecognizer 检测声音)

Posted

技术标签:

【中文标题】阻塞主线程的状态项(NSMenu 阻止 NSSpeechRecognizer 检测声音)【英文标题】:Status Item blocking the main thread (NSMenu blocking NSSpeechRecognizer from detecting sound) 【发布时间】:2012-10-17 03:33:38 【问题描述】:

我有一个NSMenu 来自NSStatusItem。我也有一个NSSpeechRecognizer。当NSMenu 打开时,语音识别器无法正常工作。它会不断显示它正在接收声音,直到我关闭菜单。即使菜单打开,我也需要它来正确检测声音。

如何让语音识别器在菜单打开时也能检测到声音?它是否需要成为“第一响应者”并优先于菜单?

我尝试设置[speechRecognizer setListensInForegroundOnly: NO],但它仍然不起作用。

如果您不明白,我非常乐意提供澄清。

这里有一些similarsituations,但我还没有完全理解。

【问题讨论】:

【参考方案1】:

问题很可能是菜单在打开时正在运行模式运行循环(用于跟踪鼠标等...),这阻碍了NSSpeechRecognizer 的功能正常。

您可以通过调出菜单然后暂停进入调试器来确认这一点。你可能会看到两个运行循环;运行模态循环的堆栈的外层、正常、一层和一层。

总的来说,从用户交互的角度来看,这是一件很奇怪的事情。弹出菜单的全部意义在于向用户提供一些命令,这些命令将在相应的菜单项被选中后执行。

如果你真的需要“点击这个东西并识别声音”,我推荐一个按钮,它可能会弹出一些 UI,然后在不使用菜单的情况下与语音识别器交互?

【讨论】:

有没有办法将NSSpeechRecognizer 放到一个单独的线程上,这样它的委托就不会在等待菜单关闭时被阻塞?或者有什么办法可以让菜单不阻塞主线程? 除非 API 被记录为允许这样做。 NSMenu 也是如此;它是菜单的一个实现细节,因为它真的不打算在您使用它时使用。 感谢您提供这些有用的信息。我决定使用NSPopover 而不是菜单来解决这个问题。

以上是关于阻塞主线程的状态项(NSMenu 阻止 NSSpeechRecognizer 检测声音)的主要内容,如果未能解决你的问题,请参考以下文章

本机调用阻塞主线程

如何在 Firebreath NPAPI 插件中将 NSMenu 连接到 NSStatusItem,以便在单击状态栏项时出现菜单?

强制更新 Cocoa App 主菜单的 NSMenu(嵌套子菜单)

从后台线程调用 startActivity 并且主线程被阻塞时,Activity 延迟启动

如何实现需求:在多个线程完成前,主线程都处于阻塞状态?CountDownLatch解决

在主线程上处理大型全局对象时如何不阻止来自工作线程的主 UI 线程