开发者社区 问答 正文

在iOS中,怎么实现一个相对精准的Timer?

今天看到一道很有意思的面试题,想了半天也不得其解,想上来问问大家。
怎么实现一个精准的Timer?

我写了如下的代码进行测试。

  1. 在主线程中。

NSTimer *tiemer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(output) userInfo:nil repeats:YES];

  • (void) output{

    NSLog(@"-------------");

    }

发现间隔时间大概在正负5毫秒之间徘徊。
就像这样:

2013-05-02 16:25:32.550 TestDemoArc[21139:907] -------------
2013-05-02 16:25:33.549 TestDemoArc[21139:907] -------------
2013-05-02 16:25:34.554 TestDemoArc[21139:907] -------------
2013-05-02 16:25:35.555 TestDemoArc[21139:907] -------------

如果在主线程中做一些操作,比如:

int j = 0;
for (int i = 0; i<100000000; i++) {
    j = j+i;
}

时间间隔会变为两秒。
就像这样:
2013-05-02 16:38:32.437 TestDemoArc[21207:907] -------------
2013-05-02 16:38:34.437 TestDemoArc[21207:907] -------------
2013-05-02 16:38:36.437 TestDemoArc[21207:907] -------------
2013-05-02 16:38:38.439 TestDemoArc[21207:907] -------------
2013-05-02 16:38:40.437 TestDemoArc[21207:907] -------------

当然,用block放到子线程里就只有1毫秒左右的偏差了。
现在想问怎么做一个Timer,保证有在1毫秒以下的偏差。

展开
收起
a123456678 2016-07-20 15:17:11 1958 分享 版权
1 条回答
写回答
取消 提交回答
  • IOS中可以使用"mach_absolute_time"获取到CPU的tickcount的计数值,可以通过"mach_timebase_info"函数获取到纳秒级的精确度 代码如下: uint64t start = 0; uint64t end = 0; uint64_t elapsed = 0;

    mach_timebase_info_t timeBaseInfo = mach_timebase_info(info);
    start = mach_absolute_time();

    // dosomething
    // .....

    end = mach_absolute_time();
    elapsed = end - start;

    // convert to nanoseconds
    uint64_t elapsedNanoSeconds = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
    但是CPU线程之间的调度肯定要花费时间,所以只能尽可能的精确。

    2019-07-17 19:58:55
    赞同 展开评论
问答分类:
问答地址: