1

我试图检测用户是否在应用程序运行时提前了他们的时钟。我目前正在通过比较两个计时器如何变化来做到这一点:[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)。

我的基本假设是否有问题,即计时器应该以相同的速度增长?我的想法是,除非出现根本性错误,否则它们不应该如此不同步——它们都在确定时间,只是从不同的点开始。

有一个更好的方法吗?我需要一个完全离线的解决方案——我们不能假设有互联网连接。

4

2 回答 2

0

您可以尝试使用 gettimeofday 来获取当前系统时间的值。这将返回自纪元以来的时间。

于 2011-10-17T21:06:38.123 回答
0

一般来说,定时器不能保证同步。也许它们来自不同的来源。也许一个与时间服务器同步。

您只关心时钟之间差异的突然变化,而不是随时间的大漂移。所以计算时钟之间差异的变化率:

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()
于 2011-10-17T21:15:08.180 回答