如何保证NSTimer始终在NSView中运行?
我在自定义 NSView
中有一个 NSTimer
。计时器设置为始终以特定间隔重复,一旦触发,计时器应更新一堆视图参数。
这一切都工作正常,但是,当视图失焦时(即右键单击工具栏以拉出菜单),计时器会延迟并且在视图失焦期间不会触发。
我的问题是,即使视图失去焦点,如何确保计时器始终触发并更新视图参数?
I have an NSTimer
inside a custom NSView
. The timer is set to always repeat at a specific interval and once it fires, the timer should update a bunch of view parameters.
This all works fine but, when the view is out of focus (i.e. right clicking on the tool bar to pull up a menu), the timer is delayed and does not fire during the time when the view is out of focus.
My question, is how do I ensure that the timer always fires and updates the view parameters even when the view is out of focus?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您执行某些事件(例如显示上下文菜单)时,运行循环将进入事件跟踪模式。这意味着仅处理某些事件。要让计时器在运行循环处于此模式时触发,请将 NSEventTrackingRunLoopMode 包含在计时器的模式列表中。
When you perform certain events (such as displaying a context menu), the run loop will enter event tracking mode. This means that only certain events will be handled. To get your timer to fire while the run loop is in this mode, include NSEventTrackingRunLoopMode in the list of modes for the timer.
一种可能的解释是:
计时器触发,事件按时添加到队列中。然而,AppKit 的大部分都不是线程安全的,所以......直到运行循环的下一次迭代你才会看到更新。 iow,事件被阻止,因为事件全部通过主运行循环/线程进行管道传输。
有道理吗?
注意:让问题变得更加复杂的是,异步绘图对于 os x(在 NSView 级别)来说是相当新的,因此请确保测试您打算支持的操作系统的所有主要版本。结果/行为会有所不同。
one potential explanation:
the timer fires, and the events are added to the queue on time. however, much of AppKit is not thread-safe so... you don't see the update until the next iteration of the run loop. iow, the events are blocked because the events are all piped through the main run loop/thread.
make sense?
note: to make issues even more complex, async drawing is fairly new to os x (at the NSView level), so ensure you test all major versions of the OS you intend to support. results/behavior will vary.