5

我的应用程序使用 mach_absolute_time 计算自上次触摸事件以来的滴答声,并在超过 10 分钟的空闲时间限制时将用户注销。

这一切在 iOS 6 上都可以正常工作,但我注意到它在 iOS 7 上的行为不正确。具体来说,当 iOS 7 设备被拔下(使用电池)时,似乎设备在进入睡眠状态后停止增加其滴答声控制台中的这一行(这发生在大约 5 分钟不活动后):

powerd[47] : 睡眠:使用 BATT(充电:99%)

因此,当我在 10 分钟后唤醒设备,并使用 mach_absolute_time 计算滴答声时,差异显示只有 5 分钟(实际上,已经过了 10 分钟)。

奇怪的是,一切正常,当设备插入电源时,滴答声继续运行。它从不显示设备在插入时将在控制台日志上进入睡眠状态(尽管屏幕确实关闭并且行为在视觉上与拔出时相同)。

我也尝试过使用clock_get_time,我在那里面临同样的问题。

当设备进入睡眠状态时,我可以在 iOS 7 中做些什么来保持 Mach 绝对时间滴答作响吗?我不想使用[[NSDate date] timeIntervalSince1970],因为用户能够操纵系统时间并绕过它。

感谢您的任何见解。

4

1 回答 1

2

原来 mach_absolute_time() 的默认行为是一旦设备进入睡眠状态就停止滴答作响。在 iOS 6 上,当应用程序使用beginBackgroundTaskWithExpirationHandler. 然而,在 iOS 7 中,允许的最长时间限制为 3 分钟(通过调用 发现这一点backgroundTimeRemaining)。这就是为什么我在 iOS 7 上看到时钟停止,但在 iOS 6 上却没有。

今天偶然发现了这个答案,这似乎很有希望。

- (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;
}

time() 在设备休眠时继续递增,但当然可以由操作系统或用户操作。但是,内核启动时间(系统上次启动时间的时间戳)也会随着系统时钟的变化而变化,因此即使这两个值都不是固定的,它们之间的偏移量也是如此。

于 2013-11-07T18:50:15.367 回答