主线程 Runloop 在打开 nsmenu 时被阻塞

Posted

技术标签:

【中文标题】主线程 Runloop 在打开 nsmenu 时被阻塞【英文标题】:Main Thread Runloop gets blocked on opening nsmenu 【发布时间】:2012-06-08 12:22:10 【问题描述】:

我有一个应用程序,它的 UI 元素包含一个 NSStatusItem 和一个菜单。在我的应用程序中,我使用NSTask 异步执行一些操作,并使用使用NSFileHandleReadCompletionNotification 获得的输出来更新菜单。但是现在每当我单击并打开菜单时,主运行循环进入NSEventTrackingRunLoopMode,并且通知发布失败。所以基本上在我的菜单打开的情况下,主线程上不会发生任何操作。现在我在this 帖子上发现了一个类似的问题,但那里接受的解决方案似乎没有帮助。我知道对于 NSNotificationCenter ,不得阻止 NSRunloopDefaultMode 。有没有办法改变这种行为???谁能帮忙???

【问题讨论】:

【参考方案1】:

我猜你有一个代表NSTaskstdoutNSFileHandle,而你已经向-readInBackgroundAndNotify 提出了请求。

正如您所发现的,问题在于它仅在运行循环处于默认模式时发出通知。如果 runloop 进入另一种模式(例如打开菜单时),那么您的通知将在主 runloop 上排队并等待直到 runloop 重新进入默认模式。

您想改用-readInBackgroundAndNotifyForModes: 方法,您可以将包含NSDefaultRunLoopModeNSEventTrackingRunLoopMode 的数组传递给该方法。这将向 runloop 指示您希望在 runloop 处于默认模式或事件跟踪模式时收到任何可用数据的通知。

【讨论】:

以上是关于主线程 Runloop 在打开 nsmenu 时被阻塞的主要内容,如果未能解决你的问题,请参考以下文章

iOS 利用runloop阻塞主线程

利用runLoop加载高清大图

iOS中RunLoop和线程的关系

RunLoop总结:RunLoop的应用场景

RunLoop

iOS中多线程原理与runloop介绍