NSTimer有时会在应用程序执行繁重的计算时冻结 [英] NSTimer sometimes freezes when app is doing heavy computation

查看:174
本文介绍了NSTimer有时会在应用程序执行繁重的计算时冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当应用程序在后台进行一些计算时,我想为某些加载点设置动画。我通过 NSTimer 实现这一点:

  self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3f 
target:self
selector:@selector(updateLoadingPoints :)
userInfo:nil
重复:YES];不幸的是,有时,当计算变得相当繁重时,该方法不会被触发,因此更新不会被执行。不会发生。



有一种方法可以让 NSTimer 更高的优先级,以确保它定期调用我的方法?

$ p

解决方案

NSTimer通过在主运行循环的队列中添加事件来工作。它是用于触摸事件和I / O数据接收事件等的相同的事件队列。您设置的时间间隔不是精确的时间表;



因为它们被实现的方式,没有办法以增加定时器的优先级。



听起来你的辅助线程占用了很多CPU时间,远离主线程,因此定时器不会触发如你所愿。



调用 performSelectorOnMainThread:将不一定有帮助,因为这些方法基本上添加一个单火计时器到主线程的事件队列。



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



让重要的工作线程运行在比主线程更低的优先级,这只是绘制东西到屏幕,但在一个人性化的应用程序,保持屏幕最新和响应用户输入通常是应用程序应该做的最重要的事情。



在实践中,主线程需要非常少的CPU,因此它不会真的减慢你的工作线程;相反,你只是确保在少量的时间,主线程需要做的事情,它很快完成。


I'd like to animate some loading points while the app is doing some computation in the background. I achieve this via an NSTimer:

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

Unfortunately, sometimes, when the computation becomes pretty heavy, the method is not fired and the updating therefore doesn't happen. It seems like all the firing is in a queue which is fired after the heavy computation.

Is there a way to give the NSTimer a higher priority to ensure that it's regularly calling my method? Or is there another way to achieve this?

解决方案

NSTimer works by adding events to the queue on the main run loop; it's the same event queue used for touch events and I/O data received events and so on. The time interval you set isn't a precise schedule; basically on each pass through the run loop, the timers are checked to see if any are due to be fired.

Because of the way they are implemented, there is no way to increase the priority of a timer.

It sounds like your secondary thread is taking a lot of CPU time away from the main thread, and so the timers don't fire as often as you would like. In other words, the main thread is starved for CPU time.

Calling performSelectorOnMainThread: won't necessarily help, because these methods essentially add a single-fire timer to the main thread's event queue. So you'll just be setting up timers in a different way.

To fix your problem, I would suggest that you increase the relative priority of the main thread by decreasing the priority of your computation thread. (See [NSThread setThreadPriority:].)

It may seem counter-intuitive to have your important worker thread running at a lower priority than the main thread, which is just drawing stuff to the screen, but in a human-friendly application, keeping the screen up to date and responding to user input usually is the most important thing that the app should be doing.

In practice, the main thread needs very little CPU, so it won't really be slowing your worker thread down; rather, you are just ensuring that for the small amount of time that the main thread needs to do something, it gets done quickly.

这篇关于NSTimer有时会在应用程序执行繁重的计算时冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆