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

今天看到一道很有意思的面试题,想了半天也不得其解,想上来问问大家。
怎么实现一个精准的Timer?
我写了如下的代码进行测试。
1.在主线程中。
NSTimer*tiemer=[NSTimerscheduledTimerWithTimeInterval:1.0target:selfselector:@selector(output)userInfo:nilrepeats:YES];
-(void)output{
NSLog(@"-------------");
}
发现间隔时间大概在正负5毫秒之间徘徊。
就像这样:
2013-05-0216:25:32.550TestDemoArc[21139:907]-------------
2013-05-0216:25:33.549TestDemoArc[21139:907]-------------
2013-05-0216:25:34.554TestDemoArc[21139:907]-------------
2013-05-0216:25:35.555TestDemoArc[21139:907]-------------
如果在主线程中做一些操作,比如:
intj=0;
for(inti=0;i<100000000;i++){
j=j+i;
}
时间间隔会变为两秒。
就像这样:
2013-05-0216:38:32.437TestDemoArc[21207:907]-------------
2013-05-0216:38:34.437TestDemoArc[21207:907]-------------
2013-05-0216:38:36.437TestDemoArc[21207:907]-------------
2013-05-0216:38:38.439TestDemoArc[21207:907]-------------
2013-05-0216:38:40.437TestDemoArc[21207:907]-------------
当然,用block放到子线程里就只有1毫秒左右的偏差了。
现在想问怎么做一个Timer,保证有在1毫秒以下的偏差。
交互式爱情
浏览 732回答 2
2回答

波斯汪

IOS中可以使用"mach_absolute_time"获取到CPU的tickcount的计数值,可以通过"mach_timebase_info"函数获取到纳秒级的精确度代码如下:uint64tstart=0;uint64tend=0;uint64_telapsed=0;mach_timebase_info_ttimeBaseInfo=mach_timebase_info(info);start=mach_absolute_time();//dosomething//.....end=mach_absolute_time();elapsed=end-start;//converttonanosecondsuint64_telapsedNanoSeconds=elapsed*sTimebaseInfo.numer/sTimebaseInfo.denom;但是CPU线程之间的调度肯定要花费时间,所以只能尽可能的精确。

aluckdog

计时器不准确的原因是,计时器只有在runLoop的一次循环中被检查,所以如果在上次循环中做了什么耗时的操作,那么计时器就被延后执行了。正确的方法应该是新开一个线程,然后在新开的线程里设定一个timer,并执行。__blockTestViewController*blockSelf=self;dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{blockSelf->_timer=[NSTimerscheduledTimerWithTimeInterval:1.0target:blockSelfselector:@selector(caculateLeftTimeForTomorrow)userInfo:nilrepeats:YES];[[NSRunLoopcurrentRunLoop]addTimer:blockSelf->_timerforMode:NSDefaultRunLoopMode];[[NSRunLoopcurrentRunLoop]run];});
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript