Аппаратные и пользовательские таймеры iPhone со временем перестают синхронизироваться - PullRequest
1 голос
/ 18 октября 2011

Я пытаюсь определить, опережает ли пользователь свои часы во время работы приложения. В настоящее время я делаю это, сравнивая, как меняются два таймера: [NSDate timeIntervalSinceReferenceDate] и mach_absolute_time.

Основной алгоритм таков:

  • В начале приложения сохраните startUserClock (timeIntervalSinceReferenceDate) и startSystemClock (mach_absolute_time, преобразованное в секунды)
  • Периодически отличать текущие значения таймеров от их соответствующих начальных значений.
  • Если различия отличаются (в пределах некоторой границы погрешности), мы должны знать, что таймеры не синхронизированы, что указывает на смену часов - теоретически это возможно только в том случае, если пользователь изменил свои часы.

Однако, похоже, что mach_absolute_time растет немного быстрее, чем timeIntervalSinceReferenceDate. В краткосрочной перспективе это не такая уж большая проблема, но со временем разница увеличивается, и мы начинаем видеть много ложных срабатываний.

Эта проблема зависит от оборудования. Я не вижу его на iPad 1 у меня, но коллега видит его на своем iPad 2, и я вижу это в симуляторе.

Я подтвердил, что нет проблемы с моим преобразованием mach_absolute_time в секунды, заменив его на CACurrentMediaTime (который использует mach_absolute_time под капотом). Я попытался изменить timeIntervalSinceReferenceDate на другие методы синхронизации (например, CFAbsoluteTimeGetCurrent).

Что-то не так с моим базовым предположением, что таймеры должны расти с той же скоростью? Я думал, что, если что-то не так в корне неправильно, они не должны быть настолько не синхронизированы - они оба определяют время, просто начиная с разных точек.

Есть ли лучший способ сделать это? Мне нужно полностью автономное решение - мы не можем подключиться к Интернету.

Ответы [ 2 ]

0 голосов
/ 18 октября 2011

В общем, таймеры не гарантируют синхронизацию. Возможно, они получены из разных источников. Возможно, один синхронизируется с сервером времени.

Вы заботитесь только о внезапных изменениях разницы между часами, а не о значительных смещениях во времени. Поэтому вычислим скорость изменения разности часов:

T_Diff := initial difference between clocks
T_Time := time as determined by one clock
Repeat forever:
  T_Diff' := new difference between clocks
  T_Time' := new time as determined by one clock

  # Check if time changed
  if abs((T_Diff'-T_Diff)/(T_Time'-T_Time)) > threshold:
    time_changed()

  # Update state
  T_Diff := T_Diff'
  T_Time := T_Time'

  wait_for_next_update()
0 голосов
/ 18 октября 2011

Вы можете попробовать использовать gettimeofday, чтобы получить значение текущего системного времени. Это возвращает время с эпохи.

...