IPhone - a question about timers and timing

I have to run the method at regular intervals (every 0.16 seconds). The tolerance may be, for example, up to 30%. Closer to 16 ms, better.

I tried NSTimers, but they are not accurate enough. I tried the threads and also had the same problem. I'm trying to send timers now.

I use this code provided by Apple:

dispatch_source_t CreateDispatchTimer(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block) { dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); if (timer) { dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway); dispatch_source_set_event_handler(timer, block); dispatch_resume(timer); } return timer; } void MyCreateTimer() { dispatch_source_t aTimer = CreateDispatchTimer(0.16 * NSEC_PER_SEC, //0.16 ms 0.048 * NSEC_PER_SEC, //30% tolerance dispatch_get_main_queue(), ^{ MyPeriodicTask(); }); // Store it somewhere for later use. if (aTimer) { MyStoreTimer(aTimer); } } 

I measure the intervals and get these moments between the execution of MyPeriodicTask ():

 0.148, 0.165, 0.148, 0.167, 0.167, 0.187, 0.167, 0.167, 0.146, 0.166, 0.167, 0.167, 0.188, 0.145, 0.243, 0.331, 0.047, 0.045, 0.168, 0.165, 0.167, 0.166, 0.167, 0.167, 0.169, 0.165, 0.166, 0.169, 0.165, 0.203, 0.130, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167, 0.167 

Note that the method starts more or less within the range of 16 ms.

given the 30% range, I expected values ​​from 0.118 to 0.224 ms, but noticed values ​​like 0.243 and 0.3131 are much higher than the range, while others, like 0.047 and 0.045 !!!! How can a method fire before a timer interval?

What can happen? Is there a way to get the exact execution of timed methods on the iPhone ???

thanks.

+4
source share
1 answer
 dispatch_source_t aTimer = CreateDispatchTimer(0.16 * NSEC_PER_SEC, //0.16 ms 0.048 * NSEC_PER_SEC, //30% tolerance dispatch_get_main_queue(), ^{ MyPeriodicTask(); }); 

You use the main queue to run the function. This means that the function is executed from RunLoop in the main thread. The execution time depends on the RunLoop tasks. If MyPeriodicTask can run in the background thread, use the global queue instead of the main queue.

 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) 

However, it can be unstable even when using the global queue. I think CADisplayLink is more stable.

Fortunately, the CADisplayLink frame rate is 60 frames per second on iOS. It is equal to 16.6 ms what you want.

+6
source

All Articles