1

出于某种原因,当我按下(单击并按住)任何控件时,我的应用程序中的 NSTimer 会冻结并且在我释放鼠标按钮之前不会触发。当我按下鼠标时,它根本不会触发。这在短时间内很好,但如果我打开一个弹出菜单或下拉组合框,它也会冻结。

我不确定我是否遗漏了什么,但这似乎是不正确的行为。

我希望能够单击 NSPopUpButtonCell 的向下箭头(甚至单击并按住 NSTableView),而不会冻结整个 NSTimer(重绘 NSView)。

任何意见/建议将不胜感激。

NSTimer 以 NSDefaultRunLoopMode 模式添加到 currentRunLoop。

4

3 回答 3

8

鼠标按下时,运行循环位于NSEventTrackingRunLoopMode. 因此,在运行循环返回到适当的模式之前,不会处理接收到 EventTracking 事件队列的任何事件。

解决此问题的方法是将计时器添加到两种模式(默认和事件跟踪)的运行循环中。

于 2011-01-07T05:52:54.580 回答
8

无需将两个或多个计时器添加到不同的运行循环或使用多线程(因为您将无法从另一个线程更新 UI),只需将计时器添加到 NSRunLoopCommonModes:

NSTimer *myTimer = [NSTimer timerWithTimeInterval:RefreshInterval target:self selector:@selector(doWork) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
于 2011-02-08T00:56:13.127 回答
0

假设您只处理应用程序中的一个线程,那么您所描述的内容是完全可以预期的。默认情况下,NSTimer' 被添加到当前NSRunLoop,在您的情况下,它也负责处理 UI 交互。当它忙于处理 UI 交互时,它无法检查您的计时器并“触发”它。

一种解决方案是使用多线程以避免这种捆绑。这是一篇关于这个主题的不错的博客文章:http: //blog.narent.com/ ?p=21

编辑:请参阅 Dave 的帖子以获取替代(和更优雅的 IMO)解决方案

另见:

于 2011-01-07T05:52:13.493 回答