计算Cocoa中两个时间点之间的秒数,即使系统时钟在中途发生变化

Dav*_*her 10 cocoa timer objective-c clock

我正在编写一个Cocoa OS X(Leopard 10.5+)最终用户程序,该程序使用时间戳来计算屏幕上显示内容的统计信息.使用重复的NSTimer运行程序时,会定期计算时间. [NSDate date]用于捕获时间戳,开始结束.以秒为单位计算两个日期之间的差异是微不足道的.

如果最终用户或ntp更改系统时钟,则会出现问题. [NSDate date]依赖于系统时钟,因此如果它被改变,Finish变量将相对于Start变形,从而显着地搞乱了时间计算.我的问题:

1. 即使系统时钟在中途改变,如何准确计算开始结束之间的时间(以秒为单位)?

我想我需要一个不变的参考时间点,所以我可以计算从那以后经过了多少秒.例如,系统正常运行时间.具有10.6 - (NSTimeInterval)systemUptime的一部分NSProcessInfo,它提供了系统正常运行时间.但是,这不起作用,因为我的应用程序必须在10.5中工作.

我尝试使用NSTimer创建时间计数器,但这不准确.NSTimer有几种不同的运行模式,一次只能运行一种.NSTimer(默认情况下)进入默认运行模式.如果用户开始操作UI足够长的时间,这将进入NSEventTrackingRunLoopMode并跳过默认运行模式,这可能导致跳过NSTimer激活,使其成为计算秒数的不准确方式.

我还考虑过创建一个单独的线程(NSRunLoop)来运行NSTimer秒计数器,使其远离UI交互.但我对多线程非常陌生,如果可能的话,我想远离它.此外,我不确定这是否会在CPU被另一个应用程序(Photoshop渲染大图像等等)绑定的情况下准确工作,导致我的NSRunLoop被搁置足够长的时间以使其陷入困境的NSTimer.

我感谢任何帮助.:)

Mik*_*lah 5

根据驱动此代码的原因,您有两种选择:

  • 对于绝对精度,请使用mach_absolute_time().它将精确地给出您调用函数的点之间的时间间隔.
  • 但是在GUI应用程序中,这实际上通常是不合需要的.相反,您需要开始和结束持续时间的事件之间的时差.如果是这样,请比较[[NSApp currentEvent] timestamp]


Dav*_*her 1

我找到了一种使用UpTime() C 函数(在<CoreServices/CoreServices.h>. 这将返回绝对时间(特定于 CPU),可以轻松转换为持续时间(毫秒或纳秒)。详细信息请参见: http://www.meandmark.com/timingpart1.html(请参阅第 3 部分中的 UpTime)

我无法mach_absolute_time()正常工作,可能是因为我缺乏这方面的知识,并且无法在网络上找到太多有关它的文档。它似乎与 抓取相同的时间UpTime(),但将其转换为双倍让我目瞪口呆。

[[NSApp currentEvent] timestamp]确实有效,但前提是应用程序正在接收 NSEvents。如果应用程序进入前台,它不会接收事件,并且[[NSApp currentEvent] timestamp]只会在 NSTimer 触发方法中继续一次又一次返回相同的旧时间戳,直到最终用户决定再次与应用程序交互。

感谢马克和迈克的帮助!你们俩肯定让我朝着正确的方向找到了答案。:)