【问题标题】:What's the minimum valid time interval of an NSTimer?NSTimer 的最小有效时间间隔是多少?
【发布时间】:2017-06-25 09:19:08
【问题描述】:

我想使用NSTimer 来增加标签上显示的数字。

这是我的代码:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

self.numberLabel = [[UILabel alloc]initWithFrame:CGRectMake(90, 90, 90, 30)];
[self.view addSubview:self.numberLabel];


self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(refreshText) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (void)refreshText{

NSDate *beginDate = [NSDate date];

static NSInteger a = 0;
a ++;

self.numberLabel.text = [NSString stringWithFormat:@"%ld",a];

if (a == 1000) {

    NSDate *endDate = [NSDate date];

    NSTimeInterval durationTime = [endDate timeIntervalSinceDate:beginDate];
    NSTimeInterval intervalTime = self.timer.timeInterval;

    NSLog(@"durationTime = %f",durationTime);
    NSLog(@"intervalTime = %f",intervalTime);

    [self.timer invalidate];
    self.timer = nil;
} 
}

控制台显示:

然后我将计时器的 timeInterval 从 0.01 更改为 0.001,控制台显示:

让我困惑的是,为什么当timeInterval为0.001时,durationTime不是0.0000056。而且,NSTimer的timeInterval有最小值我们可以设置吗?

【问题讨论】:

  • NSTimer 的分辨率充其量约为0.01s,精度不高。超过 0.02 秒的更新频率无论如何都不会引起注意
  • 您真的不想编写一个具有如此快速触发计时器的应用程序。它只会消耗电池寿命并使应用程序无响应。

标签: ios objective-c nstimer


【解决方案1】:

有更好的方法来解决您的问题。使用 CADisplayLink 而不是 NSTimer。 CADisplayLink 允许您在每次屏幕刷新时更新 UI - 尽可能快。更新 UI 的频率超过屏幕刷新的频率是没有意义的,因此 NSTimer 并不是快速 UI 更新的最佳工具。

func beginUpdates() {
  self.displayLink = CADisplayLink(target: self, selector: #selector(tick))    
  displaylink.add(to: .current, forMode: .defaultRunLoopMode)
}

func tick() {
  // update label
}

func endUpdates(){
  self.displayLink.invalidate()
  self.displayLink = nil
}

【讨论】:

    【解决方案2】:

    NSTimer 的时间段是 NSTimeInterval 类型的值,而这提供的 sub-millisecond precision 对您没有帮助。从NSTimer documentation开始:

    定时器与运行循环一起工作。运行循环维护对其计时器的强引用,因此在将计时器添加到运行循环后,您不必维护自己对计时器的强引用。

    要有效地使用计时器,您应该了解运行循环的运行方式。有关详细信息,请参阅线程编程指南。

    计时器不是实时机制。如果计时器的触发时间发生在长时间的运行循环调用期间或运行循环处于不监视计时器的模式下,则计时器不会触发,直到运行循环下次检查计时器。因此,计时器触发的实际时间可能要晚得多。另请参阅计时器容差。

    因此NSTimer 的最小时间间隔与运行循环迭代的长度相关。虽然内部优化(如果存在)可以在设置间隔后立即触发计时器,如果间隔真的很小,那么您将获得的最短时间取决于计时器所在的运行循环迭代的剩余执行时间set,这对于通用编程来说几乎是不确定的。

    如果您真的需要一个高分辨率计时器(请参阅@bbum 对您问题的评论),那么您需要研究该主题 - 只需搜索“高分辨率计时 macOS”之类的内容即可起点。

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多