除了mach_absolute_time()之外的iOS真正的单调时钟

时间:2013-12-28 17:26:26

标签: ios

我的iOS应用程序需要一个与我服务器时钟同步的自定义时钟。所有同步逻辑都已完成。

我的时钟基于mach_absolute_time(),您可以从中计算自设备启动以来经过的时间。问题是当设备进入睡眠模式时(通过按下屏幕锁定键并且没有应用程序在后台运行),马赫时间滴答暂停。当手机被唤醒时,马赫时间会恢复,但不会占用手机睡着的时间。

这是我计算自启动以来经过的时间的方式(但它不会考虑设备处于睡眠状态的时间)

- (long long) elapsedTimeMillis {
    uint64_t elapsedTimeNano = 0;

    mach_timebase_info_data_t timeBaseInfo;
    mach_timebase_info(&timeBaseInfo);

    elapsedTimeNano = mach_absolute_time() * timeBaseInfo.numer / timeBaseInfo.denom;
    return (long long)(elapsedTimeNano / 1000000);
}

这有完全相同的结果:

- (long long) elapsedTimeMillis {
    clock_serv_t cclock;
    mach_timespec_t mts;

    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
    clock_get_time(cclock, &mts);
    mach_port_deallocate(mach_task_self(), cclock);

    return mts.tv_nsec / 1000000 + mts.tv_sec * 1000;
}

NSDate,CFAbsoluteTimeGetCurrent()或类似选项不是一个选项,因为它们会受到用户同步或手动更改的设备时间的影响。

是否有任何方法可以通过不会来回跳转的不间断时钟来获取iOS时间?

1 个答案:

答案 0 :(得分:2)

这就是诀窍:

请参阅:Getting iOS system uptime, that doesn't pause when asleep

- (time_t)uptime
{
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -1;
    (void)time(&now);
    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0)
    {
        uptime = now - (boottime.tv_sec);
    }

    return uptime;
}

自上次启动后返回SECONDS。设备休眠不会影响它,用户也不会同步电话时间同步或电话时间。不幸的是,它不会返回毫秒或纳秒。