【发布时间】:2011-01-11 05:25:15
【问题描述】:
我在自定义NSView 中有一个NSTimer。计时器设置为始终以特定间隔重复,一旦触发,计时器应该更新一堆视图参数。
这一切都很好,但是当视图失焦时(即右键单击工具栏以拉出菜单),计时器会延迟并且在视图失焦期间不会触发。
我的问题是,即使视图失焦,如何确保计时器始终触发并更新视图参数?
【问题讨论】:
我在自定义NSView 中有一个NSTimer。计时器设置为始终以特定间隔重复,一旦触发,计时器应该更新一堆视图参数。
这一切都很好,但是当视图失焦时(即右键单击工具栏以拉出菜单),计时器会延迟并且在视图失焦期间不会触发。
我的问题是,即使视图失焦,如何确保计时器始终触发并更新视图参数?
【问题讨论】:
当您执行某些事件(例如显示上下文菜单)时,运行循环将进入事件跟踪模式。这意味着只会处理某些事件。要在运行循环处于此模式时触发计时器,请将 NSEventTrackingRunLoopMode 包含在计时器的模式列表中。
NSTimer *timer = [NSTimer timerWithTimeInterval:theInterval target:theTarget selector:theSelector userInfo:theUserInfo repeats:shouldRepeat];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
【讨论】:
一种可能的解释:
计时器触发,事件按时添加到队列中。但是,大部分 AppKit 都不是线程安全的,所以......直到运行循环的下一次迭代,您才能看到更新。 iow,事件被阻塞了,因为这些事件都是通过主运行循环/线程进行管道传输的。
有意义吗?
注意:为了使问题更加复杂,异步绘图对于 os x(在 NSView 级别)来说是相当新的,因此请确保您测试您打算支持的所有主要版本的操作系统。结果/行为会有所不同。
【讨论】: