how to get a accurate timer in ios

2020-03-31 06:38发布

I am doing an app which needs a timer. I have tried NSTimer but NSTimer always loses or gets delayed. Is there a class in the iOS SDK which can log time accurately. An accuracy between 20ms and 40ms is okay. I'd like to be able to change an image in a fixed time interval.

NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:.04f target:self    selector:@selector(timer1) userInfo:nil repeats:YES];
- (void)timer1
{
   NSLog(@"timer1 timer %@",[NSDate date]);
}

4条回答
放我归山
2楼-- · 2020-03-31 06:48

Have you considered using the dispatch source timer? From what I observed thus far, this timer is very precise.

Here is a link to one of apple's programming guide:

http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/GCDWorkQueues/GCDWorkQueues.html#//apple_ref/doc/uid/TP40008091-CH103-SW1

Just check the sub section: "Creating a timer".

查看更多
小情绪 Triste *
3楼-- · 2020-03-31 07:00

Perhaps your results are a false negative due to how you're testing NSDate?

This question discusses how to get millisecond accuracy from NSDate.

查看更多
▲ chillily
4楼-- · 2020-03-31 07:01

NSTimer is not a high-resolution timer. From the NSTimer class documentation:

Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds.

In addition to link suggested by @CJ Foley, you can check out dispatch_after function.

查看更多
仙女界的扛把子
5楼-- · 2020-03-31 07:01

Use CADisplayLink for this. It fires at the system frame rate: 60 fps, or 17 ms.

If you want a longer interval you can set it to fire at a multiple of the frame rate, e.g. every 2nd or 3rd frame.

CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(timer1)];
displayLink.frameInterval = 2;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

It's meant to be used for UI that should update every n frames.

Don't use dispatch_after. As the name would suggest, the only guarantee is that your block will execute after a particular time. If anything blocks the thread, your block will have to wait.

查看更多
登录 后发表回答