2012-03-16 2 views
0

Я делаю приложение, которому нужен таймер. Я пробовал NSTimer, но NSTimer всегда теряет или задерживается. Есть ли класс в SDK iOS, который может записывать время точно. Точность между 20 мс и 40 мс в порядке. Я хотел бы иметь возможность изменять изображение в фиксированный временной интервал.Как получить точный таймер в ios

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

Разве ваш период и ваш ключ переключения нарушены? – dasdom

+0

Проблема заключается не в точности таймера, а в задержке очередности с момента запуска таймера до момента вызова сервисной процедуры. Если вы используете схему, которая работает в потоке пользовательского интерфейса, тогда нет способа обойти это. –

ответ

3

NSTimer не является таймером с высоким разрешением. Из NSTimer документации класса:

Из-за различных источников входного сигнала типичный цикл запуска управляет, эффективное разрешение временного интервала для таймера ограничено порядка 50-100 миллисекунд.

В дополнение к ссылке, предложенной @CJ Foley, вы можете проверить функцию dispatch_after.

+0

+1 - моя мысль точно! –

+0

Я также видел это в документации класса nstimer, поэтому я хочу найти некоторый эффективный класс, чтобы получить точный временной интервал, чтобы сделать какое-то периодическое действие. – joebo

+0

Как сказано в ответе bcattle, dispatch_after не гарантирует выполнение в определенное время, только _after_ определенное время. 'CADisplayLink' - лучшая ставка. – Bernem

0

Возможно, ваши результаты являются ложными отрицательными из-за того, как вы тестируете NSDate?

This question обсуждает, как получить миллисекундную точность от NSDate.

+1

NSDate действительно хороший класс, чтобы получить точное время, но в моем вопросе я хочу получить точный интервал времени, чтобы сделать какое-то периодическое действие, точно так же, как nstimer – joebo

2

Считаете ли вы использование таймера источника отправки? Из того, что я наблюдал до сих пор, этот таймер очень точен.

Вот ссылка на один из руководства по программированию яблока:

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

Просто проверьте раздел подменю: «Создание таймера».

3

Используйте CADisplayLink для этого. Он срабатывает при частоте кадров системы: 60 кадров в секунду или 17 мс.

Если вы хотите более длинный интервал, вы можете установить его для срабатывания с кратным частоте кадров, например. каждый второй или третий кадр.

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

Он предназначен для использования в пользовательский интерфейс, который должен обновляться каждые п кадров.

Не использовать dispatch_after. Как следует из названия, единственной гарантией является то, что ваш блок выполнит после определенное время. Если что-то блокирует поток, ваш блок должен будет ждать.

+0

Это невероятно полезно, я понятия не имел, что он существовал раньше.В течение многих лет я изогнул себя в крендельки в среде Windows, пытаясь добиться правильной синхронизации анимации с частотой обновления, и вот этот простой компонент iOS * включен * по частоте обновления. – MusiGenesis

Смежные вопросы