1

我想在应用程序在后台进行一些计算时为一些加载点设置动画。我通过一个NSTimer

    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3f
                                             target:self 
                                           selector:@selector(updateLoadingPoints:) 
                                           userInfo:nil 
                                            repeats:YES];

不幸的是,有时,当计算变得非常繁重时,该方法不会被触发,因此不会发生更新。似乎所有的触发都在一个队列中,在繁重的计算之后触发​​。

有没有办法给予NSTimer更高的优先级以确保它定期调用我的方法?还是有另一种方法可以实现这一目标?

4

4 回答 4

3

NSTimer 通过在主运行循环的队列中添加事件来工作;它与用于触摸事件和 I/O 数据接收事件等的事件队列相同。您设置的时间间隔不是一个精确的时间表;基本上在每次通过运行循环时,都会检查计时器以查看是否要触发任何计时器。

由于它们的实现方式,没有办法增加计时器的优先级。

听起来您的辅助线程正在从主线程中占用大量 CPU 时间,因此计时器不会像您希望的那样频繁触发。换句话说,主线程缺乏CPU 时间。

调用performSelectorOnMainThread:不一定有帮助,因为这些方法本质上是在主线程的事件队列中添加一个单次触发计时器。因此,您只需以不同的方式设置计时器。

为了解决您的问题,我建议您通过降低计算线程的优先级来增加主线程的相对优先级。(见。)[NSThread setThreadPriority:]

让重要的工作线程以低于主线程的优先级运行似乎违反直觉,主线程只是将内容绘制到屏幕上,但在人性化的应用程序中,使屏幕保持最新并响应用户输入通常是应用程序应该做的最重要的事情。

实际上,主线程只需要很少的 CPU,因此它不会真正减慢您的工作线程;相反,您只是确保在主线程需要做某事的一小段时间内,它可以快速完成。

于 2012-01-09T19:47:26.170 回答
0

计时器被添加到它被调度的运行循环中。如果您在辅助线程(例如您的工作线程)上创建计时器,那么您很有可能还将它安排在辅助线程上。

您希望主线程上的 UI 更新。因此,您希望将计时器安排在主线程上。如果您的更新仍然很慢,也许您的主线程可以做更少的工作,并确保您的线程数量非常少,并且您正在适当地锁定。

我怀疑您在辅助线程上创建了它,该辅助线程没有像计时器想要触发那样频繁地运行运行循环。如果它在后台做很多(长时间的)工作,并且没有运行运行循环,那么计时器将没有机会触发,因为当它的线程仍在处理时,消息没有机会被触发.

于 2012-01-09T22:17:48.567 回答
-1

使用 performSelectorInBackground:withObject 在单独的线程上执行计算。总是在你的 UI 循环中做尽可能少的事情,因为这里所做的任何工作都会阻止鼠标点击、导致 SPoD/沙滩球和延迟计时器处理程序。

我怀疑不仅仅是您的 TIMER 没有响应,而是整个 UI 都没有响应。

很抱歉在我的早期版本中调用了错误的 API - 我的复制/粘贴失败。

于 2012-01-09T19:27:30.610 回答
-1

从单独的线程而不是主线程进行计时器调用。这肯定会使它与您的其他主线程的处理分开,这将为您提供所需的结果。

于 2012-01-09T10:37:02.083 回答