NSTimer - 非阻塞回调

时间:2012-08-22 10:58:08

标签: iphone objective-c ios nstimer

我对Objective-c有些新意。所以,如果我的问题或代码看起来很奇怪,那就可以解释原因。我有一个NSTimer,每0.033秒被触发一次。

timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(timerCallback) userInfo:nil repeats:YES];

选择器功能如下所示:

BOOL running = false;
- (void) timerCallback
{
   if (running) {
    return;
   }
   running = true;
   //Do some stuff
   running = false;
}

事实是,无论维持什么同步,都必须以这些间隔触发函数timerCallback。 (跳过详细信息)

但是......事实证明,timerCallback函数会导致NSTimer停止并在恢复之前等待它完成?

我有什么选择来维持间隔? timerCallback函数可以在单独的线程中执行吗?有比NSTimer更好的选择吗?也许是一个单独的线程开始?

2 个答案:

答案 0 :(得分:2)

我建议使用这样的东西,以防止阻塞。

BOOL running = false;
- (void) timerCallback
{
   if (running) {
    return;
   }

  [(NSOperationQueue*)_myOperationQueue addOperationWithBlock:^{
     running = true;
     //do Some Stuff
     running = false 
  }];
}

答案 1 :(得分:0)

计时器将尝试维持随时间平均的所需发射间隔 - 因为由于NSTimer和NSRunLoop的设计,它无法提供精确的时序。如果你的计时器中的代码超过0.033秒,我不确定计时器是否会跳过一个电话 - 它可能

尝试此实验 - 设置计时器,然后注释掉所有工作,并记录时间。它应该非常接近所需的时间。也就是说,如果您正在触摸UI,那么每秒30次调用就接近您可能获得的最高性能。

最小化变化量的一种策略是将您正在执行的所有代码放在一个块中,然后将其分派到主队列,或者更好地将其分派到并发线程。这样你就可以在很短的时间内从电话中回来。

如果您不这样做,请查看CADisplayLink。您可以使用此功能获得非常精确的回调,因为它以非常高的优先级运行。但是,你不能在回调中做任何实质性的事情,因为你只能获得一小段时间。但是,您可以将块分派到队列以便在主队列(主线程)上进行处理。