出于某种原因,当我按下任何控件上的(单击并按住)时,我的应用程序中的NSTimer会冻结,直到我释放鼠标按钮才会触发。我按下鼠标时根本不会触发。这对于短期来说很好,但如果我打开一个弹出菜单,或者组合框掉落,它也会冻结。
我不确定是否有遗漏的东西,但似乎这是不正确的行为。
我希望能够点击NSPopUpButtonCell的向下箭头(甚至点击并按住NSTableView),而不会冻结整个NSTimer(重绘NSView)。
任何意见/建议将不胜感激。
使用模式NSDefaultRunLoopMode将NSTimer添加到currentRunLoop。
答案 0 :(得分:8)
当鼠标停止运行时,运行循环位于NSEventTrackingRunLoopMode
。因此,在runloop返回到适当的模式之前,任何不接收到EventTracking事件队列的事件都不会得到服务。
解决这个问题的方法是将定时器添加到两种模式的runloop(默认和事件跟踪)。
答案 1 :(得分:8)
不是将两个或多个计时器添加到不同的runloops或使用多线程(因为您无法从另一个线程更新UI),只需将计时器添加到NSRunLoopCommonModes:
NSTimer *myTimer = [NSTimer timerWithTimeInterval:RefreshInterval target:self selector:@selector(doWork) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
答案 2 :(得分:0)
假设您只是处理应用程序中的一个线程,那么您所描述的内容是完全可以预期的。默认情况下,NSTimer
被添加到当前NSRunLoop
中,在您的情况下,它还负责处理UI交互。当它与处理UI交互相关时,它无法检查您的计时器并“触发”它。
解决方案是使用多线程以避免这种束缚。这是一篇关于这个主题的好文章:http://blog.narent.com/?p=21
编辑:请参阅Dave的帖子,了解替代方案(以及更优雅的IMO)解决方案
另见: