使用NSTimer实现具有指数退避的重试逻辑

时间:2012-04-23 04:22:33

标签: objective-c ios foundation

我正在尝试使用NSTimer实现指数退避的重试逻辑。 我的代码如下所示:

-(void)start
{
  [NSTimer scheduledTimerWithTimeInterval:0.0 target:self
    selector:@selector(startWithTimer:) userInfo:nil repeats:NO];
}

-(void)startWithTimer:(NSTimer *)timer
{
  if (!data.ready) {
    // timer.timeInterval == 0.0 ALWAYS!
    NSTimeInterval newInterval = timer.timeInterval >= 0.1 ? timer.timeInterval * 2 : 0.1;
    newInterval = MIN(60.0, newInterval);
    NSLog(@"Data provider not ready. Will try again in %f seconds.", newInterval);
    NSTimer * startTimer = [NSTimer scheduledTimerWithTimeInterval:newInterval target:self
        selector:@selector(startWithTimer:) userInfo:nil repeats:NO];
    // startTimer.timeInteval == 0.0 ALWAYS!
    return;
  }

  ...
}

我遇到的问题是计时器NSTimer scheduledTimerWithTimeInterval似乎忽略了我提供的间隔并始终将其设置为0.0。我在这里做错了什么建议?

1 个答案:

答案 0 :(得分:5)

Apple文档可以说明timeInterval上的NSTimer属性。

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html

  

如果接收器是非重复定时器,则返回0(即使设置了时间间隔)。

您需要使用其他方法来跟踪计时器间隔应该是什么。我推荐你上课的iVar。

-(void)start
{
  _timeInterval = 0.0;
  [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self
    selector:@selector(startWithTimer:) userInfo:nil repeats:NO];
}

-(void)startWithTimer:(NSTimer *)timer
{
  if (!data.ready) {
    _timeInterval = _timeInterval >= 0.1 ? _timeInterval * 2 : 0.1;
    _timeInterval = MIN(60.0, _timeInterval);
    NSLog(@"Data provider not ready. Will try again in %f seconds.", _timeInterval);
    NSTimer * startTimer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self
        selector:@selector(startWithTimer:) userInfo:nil repeats:NO];
    return;
  }

  ...
}