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]);
}
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.
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.
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".
Perhaps your results are a false negative due to how you're testing NSDate?
This question discusses how to get millisecond accuracy from NSDate.