我的应用程序使用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中做些什么来保持设备进入睡眠状态时的马赫绝对时间?我不想使用[[NSDate date] timeIntervalSince1970]
,因为用户可以操纵系统时间并绕过它。
感谢您的任何见解。
答案 0 :(得分:2)
事实证明,mach_absolute_time()的默认行为是在设备进入休眠状态时停止滴答。在iOS 6上,当使用beginBackgroundTaskWithExpirationHandler
将应用程序放入后台时,我能够将暂停时间延长10分钟。但是,在iOS 7中,允许的最长时间限制在3分钟(通过调用backgroundTimeRemaining
来发现这一点)。这就是为什么我在iOS 7上看到时钟停止的原因,但在iOS 6上却没有。
今天偶然发现this answer,这似乎很有希望。
- (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()在设备处于睡眠状态时继续递增,但当然可以由操作系统或用户操作。但是,内核启动时间(系统上次启动时的时间戳)也会在系统时钟更改时发生变化,因此即使这两个值都不固定,它们之间的偏移也是如此。