在Cocoa中计算两个时间点之间的秒数,即使系统时钟在中途发生了变化 [英] Calculating number of seconds between two points in time, in Cocoa, even when system clock has changed mid-way

查看:159
本文介绍了在Cocoa中计算两个时间点之间的秒数,即使系统时钟在中途发生了变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个Cocoa OS X(Leopard 10.5+)终端用户程序,它使用时间戳来计算屏幕上显示的东西的时间长度的统计信息。当程序使用重复的NSTimer运行时周期性地计算时间。 [NSDate date] 用于捕获时间戳,开始完成。以秒为单位计算两个日期之间的差异是微不足道的。

I'm writing a Cocoa OS X (Leopard 10.5+) end-user program that's using timestamps to calculate statistics for how long something is being displayed on the screen. Time is calculated periodically while the program runs using a repeating NSTimer. [NSDate date] is used to capture timestamps, Start and Finish. Calculating the difference between the two dates in seconds is trivial.

如果最终用户或ntp更改系统时钟,则会出现问题。 [NSDate date] 依赖于系统时钟,因此如果更改,完成变量将相对于强>,弄乱了时间计算显着。我的问题:

A problem occurs if an end-user or ntp changes the system clock. [NSDate date] relies on the system clock, so if it's changed, the Finish variable will be skewed relative to the Start, messing up the time calculation significantly. My question:

1。即使系统时钟在中途更改,如何准确计算开始完成之间的时间(以秒为单位)?

1. How can I accurately calculate the time between Start and Finish, in seconds, even when the system clock is changed mid-way?

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

I'm thinking that I need a non-changing reference point in time so I can calculate how many seconds has passed since then. For example, system uptime. 10.6 has - (NSTimeInterval)systemUptime, part of NSProcessInfo, which provides system uptime. However, this won't work as my app must work in 10.5.

我已经尝试使用NSTimer创建时间计数器,但这是不准确的。 NSTimer有几种不同的运行模式,一次只能运行一个。 NSTimer(默认情况下)将进入默认运行模式。如果用户开始操作UI达足够长的时间,这将进入 NSEventTrackingRunLoopMode ,并跳过默认运行模式,这可能导致NSTimer触发被跳过,

I've tried creating a time counter using NSTimer, but this isn't accurate. NSTimer has several different run modes and can only run one at a time. NSTimer (by default) is put into the default run mode. If a user starts manipulating the UI for a long enough time, this will enter NSEventTrackingRunLoopMode and skip over the default run mode, which can lead to NSTimer firings being skipped, making it an inaccurate way of counting seconds.

我也想过创建一个单独的线程(NSRunLoop)来运行一个NSTimer二计数器,避免UI交互。但我是多线程的新手,如果可能的话,我想远离。此外,我不知道如果这将工作准确地在事件中CPU被另一个应用程序(Photoshop渲染一个大的图像,等等),导致我的NSRunLoop被搁置足够长的时间,弄乱它的NSTimer。

I've also thought about creating a separate thread (NSRunLoop) to run a NSTimer second-counter, keeping it away from UI interactions. But I'm very new to multi-threading and I'd like to stay away from that if possible. Also, I'm not sure if this would work accurately in the event the CPU gets pegged by another application (Photoshop rendering a large image, etc...), causing my NSRunLoop to be put on hold for long enough to mess up its NSTimer.

我很感激任何帮助。 :)

I appreciate any help. :)

推荐答案

我想出了一种方法来使用 UpTime在< CoreServices / CoreServices.h> 中提供。这将返回绝对时间(特定于CPU),可以轻松地将其转换为持续时间(毫秒或纳秒)。详情请参阅: http://www.meandmark.com/timingpart1.html (下方) 3 for UpTime)

I figured out a way to do this using the UpTime() C function, provided in <CoreServices/CoreServices.h>. This returns Absolute Time (CPU-specific), which can easily be converted into Duration Time (milliseconds, or nanoseconds). Details here: http://www.meandmark.com/timingpart1.html (look under part 3 for UpTime)

我无法获得 mach_absolute_time()才能正常工作,知识,而不能在网上找到很多关于它的文档。它似乎抓住与 UpTime()相同的时间,但把它转换为双左我茫然。

I couldn't get mach_absolute_time() to work properly, likely due to my lack of knowledge on it, and not being able to find much documentation on the web about it. It appears to grab the same time as UpTime(), but converting it into a double left me dumbfounded.

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

[[NSApp currentEvent] timestamp] did work, but only if the application was receiving NSEvents. If the application went into the foreground, it wouldn't receive events, and [[NSApp currentEvent] timestamp] would simply continue to return the same old timestamp again and again in an NSTimer firing method, until the end-user decided to interact with the app again.

感谢您的帮助Marc和Mike!你们都明确地把我送到正确的方向导致答案。 :)

Thanks for all your help Marc and Mike! You both definitely sent me in the right direction leading to the answer. :)

这篇关于在Cocoa中计算两个时间点之间的秒数,即使系统时钟在中途发生了变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆