要在 iOS 上获得准确的时间测量,应使用
mach_absolute_time()
。或者 CACurrentMediaTime()
,它是基于 mach_absolute_time()
的。这在此 Apple Q&A 中有记录,并且在几个 StackOverflow 答案中也有解释(例如 https://stackoverflow.com/a/17986909、https://stackoverflow.com/a/30363702)。
mach_absolute_time()
返回的值什么时候回绕? CACurrentMediaTime()
返回的值什么时候回绕?这会在任何现实的时间跨度内发生吗? mach_absolute_time()
的返回值是 uint64
类型,但我不确定这如何映射到真实的时间跨度。
您引用的文档指出
mach_absolute_time
取决于 CPU,因此我们无法确定它必须经过多长时间才能换行。在模拟器上,mach_absolute_time
是纳秒,因此如果它在 UInt64.max
处回绕,则相当于 585 年。在我的 iPhone 7+ 上,每秒 24,000,000 mac_absolute_time
,相当于 24,000 年。最重要的是,mach_absolute_time
捕获的理论最大时间量将根据 CPU 的不同而有所不同,但在任何实际应用中您都不会遇到这种情况。
就其价值而言,与您发现的各种帖子一致,
CFAbsoluteTimeGetCurrent
文档警告:
重复调用该函数并不能保证结果单调递增。由于与外部时间参考同步或由于用户明确更改时钟,系统时间可能会减少。
因此,如果您想要准确的经过时间,您绝对不想使用
NSDate
/Date
或 CFAbsoluteTimeGetCurrent
。两者都不能保证值的单调递增。
CACurrentMediaTime
,因为它享受mach_absolute_time
的好处,但它为我将其转换为秒,这使得它使用起来非常简单。它和 mach_absolute_time
都不会在任何现实的时间段内循环。
ContinuousClock
。虽然它没有正式概述其实现细节(可能是为了将来提供不同实现的灵活性和/或在不同平台上采用不同的实现),但它说:
测量时间的时钟,该时钟始终递增并且在系统睡眠时不会停止递增。 …
参考框架……可能会绑定到进程启动、机器启动或其他一些本地定义的参考点。这意味着时刻只能在程序执行期间在本地进行比较。
该时钟适合执行的高分辨率测量。