主线程Runloop在打开nsmenu时被阻塞 [英] Main Thread Runloop gets blocked on opening nsmenu

查看:472
本文介绍了主线程Runloop在打开nsmenu时被阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,其UI元素包括 NSStatusItem 和菜单。在我的应用程序中,我使用 NSTask 异步执行一些操作,我使用 NSFileHandleReadCompletionNotification 获得的输出更新菜单。但现在每当我点击并打开菜单,主runloop进入 NSEventTrackingRunLoopMode ,通知过帐失败。所以基本上我的菜单打开,没有操作发生在主线程。现在我发现一个类似的问题,在 post但接受的解决方案似乎没有帮助。我理解对于 NSNotificationCenter ,不能阻止 NSRunloopDefaultMode 。有没有反正改变这个bahaviour ???任何人都可以帮忙。

I have an application for which the UI element includes an NSStatusItem and a menu. Inside my application , I am using NSTask asynchronously to perform some operation and I am using the output obtained using the NSFileHandleReadCompletionNotification to update the menu. But now whenever I click and open the menu , the main runloop goes into NSEventTrackingRunLoopMode and the notification posting fails. So basically with my menu open , no operation takes place on the main thread. Now I found a similar problem on this post but the accepted solution there does not seem to help. I understand that for NSNotificationCenter , the NSRunloopDefaultMode must not be blocked. Is there anyway to alter this bahaviour??? Can anyone please help ???

推荐答案

我猜测你有一个 NSFileHandle 代表 NSTask stdout ,并且您已要求 -readInBackgroundAndNotify

What I'm guessing is that you have an NSFileHandle that represents the NSTask's stdout, and you've asked it to -readInBackgroundAndNotify.

您遇到的问题是这仅在runloop处于默认模式时通知。如果runloop进入另一个模式(例如菜单打开时),那么你的通知将在主runloop上排队,并等待runloop重新进入默认模式。

The problem with this, as you've found, is that this only notifies when the runloop is in the default mode. If the runloop enters another mode (such as when a menu is open), then your notifications will queue up on the main runloop and will wait until the runloop re-enters the default mode.

您要使用的是 -readInBackgroundAndNotifyForModes: 方法,您将传递一个数组, c $ c> NSDefaultRunLoopMode 和 NSEventTrackingRunLoopMode 。当runloop处于默认模式或事件跟踪模式时,这将向runloop指示您希望通知任何可用数据。

What you want to use instead is the -readInBackgroundAndNotifyForModes: method, to which you would pass an array containing both NSDefaultRunLoopMode and NSEventTrackingRunLoopMode. This would indicate to the runloop that you want to be notified of any available data when the runloop is either in the default mode or the event tracking mode.

这篇关于主线程Runloop在打开nsmenu时被阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆