我正在开发一款使用NSTimer进行倒计时的iOS应用。这很容易被用户篡改:例如,如果用户切换出应用程序,手动关闭应用程序,更改设备时钟,然后重新进入,则必须重新创建计时器。另一种情况是:用户锁定设备,进入低功耗模式(需要重新创建定时器),并且在游戏再次打开之前时钟自动设置。如果发生这种情况,我将无法准确确定自应用程序关闭以来已经过了多少时间,因为设备时钟已经发生变化。
Tl; dr:倒计时器有时必须在设备时钟更改后重新创建。这个问题通常是如何处理的?
答案 0 :(得分:3)
每当你依靠系统时钟进行精确计时时,即使用户没有故意篡改时钟,你也会遇到麻烦。通常,通过稍微增加或减小一秒的长度来校正时钟漂移,以允许时钟在几分钟的时间段内漂移回对准。如果您需要准确的计时,您可以使用与系统正常运行时间而非系统时钟相关的mach_absolute_time()
,或者您可以使用Grand Central Dispatch。 dispatch_after()
函数采用dispatch_time_t
,可以使用挂号时间(例如系统时钟)表示,也可以作为DISPATCH_TIME_NOW
的偏移量(忽略挂钟)。
答案 1 :(得分:0)
供将来参考,关于OSX(以及iOS)中不同的计时系统:
衡量任何操作速度的一种方法,包括启动时间, 是使用系统例程来获取开始时的当前时间 操作结束。一旦你有两个时间值,你可以采取 区别并记录结果。
这种技术的优点是它可以让你测量 特定代码块的持续时间。 Mac OS X包括几个 获得当前时间的不同方式:
- mach_absolute_time读取CPU时基寄存器并且是 其他时间测量功能的基础。
- Core Services UpTime功能提供纳秒分辨率 用于时间测量。
- BSD gettimeofday函数(在
<sys/time.h>
中声明)提供了
微秒分辨率。 (注意,这个功能会产生一些开销但是 对于大多数用途来说仍然是准确的。)- 在Cocoa中,您可以创建一个当前时间为的NSDate对象 操作开始然后使用
timeIntervalSinceDate:获取时差的方法。
来源:Launch Time Performance Guidelines, "Gathering Launch Time Metrics"。