iOS的开机时间可以漂移吗?

我正在使用此代码来确定我的iOS设备上次重新启动的时间:

int mib[MIB_SIZE]; size_t size; struct timeval boottime; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; size = sizeof(boottime); if (sysctl(mib, MIB_SIZE, &boottime, &size, NULL, 0) != -1) { return boottime.tv_sec; } return 0; 

这一次我看到一些exception。 特别是,我省了很长时间,几个星期后又检查了上面代码返回的值。

我不确定,但我想我正在看到一些漂移。 这对我没有任何意义。 我不转换到NSDate,以防止漂移。 我认为引导时间是由内核启动时logging的,不再计算,只是存储。 但是,iOS可以将启动时间保存为一个NSDate,有任何固有的漂移问题呢?

虽然iOS内核是封闭的,但是我们可以认为它大部分与开源的OSX内核是一样的 。

osfmk/kern/clock.c有这样的function:

 /* * clock_get_boottime_nanotime: * * Return the boottime, used by sysctl. */ void clock_get_boottime_nanotime( clock_sec_t *secs, clock_nsec_t *nanosecs) { spl_t s; s = splclock(); clock_lock(); *secs = (clock_sec_t)clock_boottime; *nanosecs = 0; clock_unlock(); splx(s); } 

clock_boottime被声明为:

 static uint64_t clock_boottime; /* Seconds boottime epoch */ 

最后对这个函数的评论显示它确实可以改变:

 /* * clock_set_calendar_microtime: * * Sets the current calendar value by * recalculating the epoch and offset * from the system clock. * * Also adjusts the boottime to keep the * value consistent, writes the new * calendar value to the platform clock, * and sends calendar change notifications. */ void clock_set_calendar_microtime( clock_sec_t secs, clock_usec_t microsecs) { ... 

更新以回答来自OP的查询

我不确定clock_set_calendar_microtime()被调用的频率,因为我不熟悉内核的内部工作原理; 然而,它调整clock_boottime值,并clock_initialize_calendar()初始化clock_bootime值,所以我可以说,它可以被称为不止一次。 我一直无法find任何使用它的电话:

 $ find . -type f -exec grep -l clock_set_calendar_microtime {} \;