【问题标题】:How to display time in seconds in Cocoa efficiently?如何在 Cocoa 中有效地以秒为单位显示时间?
【发布时间】:2009-11-05 01:46:42
【问题描述】:

我想在文本字段中显示应用程序中的时间(包括秒数),非常简单。我目前所做的是创建一个每 0.1 秒运行一次的 NSTimer,它获取系统时间并更新文本字段。这似乎是一种非常低效的方法来实现这一点。有没有更好的办法?

【问题讨论】:

    标签: objective-c cocoa macos nstimer


    【解决方案1】:

    您是否以十分之一秒(或更精细)的分辨率显示它?

    如果是这样,我认为没有问题。通常,轮询很糟糕,因为您检查的内容可能没有改变,但时间不会停止在您身上。所以一个十分之一秒的计时器就可以了。

    如果不是,则创建一个间隔为所需分辨率的计时器,然后获取其触发日期,将其向下舍入到所需分辨率(例如,如果您每秒更新一秒),并将其设置为新的触发日期.然后,您的计时器只会在适合更新时钟视图的时间同时触发。

    请注意,虽然时间总是在移动,但它并不总是线性移动:它可能会向前或向后跳一小时或半小时,或者如果用户(或 ntpd)更改了系统时钟设置,则可以任意跳动。在 Mac OS X 10.6 及更高版本上,您可以观察NSSystemClockDidChangeNotification,并在发生这种情况时重新调整计时器的触发日期。

    【讨论】:

    • 我只以一秒的分辨率显示。但是,如果我在一秒钟内进行轮询,例如,我的文本更新可能会晚 0.9 秒。如果用户在菜单栏上的时钟上设置了“显示秒数”选项,我希望应用程序显示在菜单栏更改秒数的确切时间更新时间文本,因此每秒轮询 10 次。
    • 如果您正确设置了开火日期,您将不会迟到 0.9 秒。计时器必须非常滞后才能完成——如果它滞后 0.9 秒,将其间隔设置为 0.1 秒将无济于事。
    【解决方案2】:

    如何使用每秒运行的 NSTimer,然后检查触发时间并确保它恰好在一秒的开始。您可以使用initWithFireDate:interval:target:selector:userInfo:repeats: 或在创建计时器后使用setFireDate: 适当地设置下一次调用时间:

    NSTimeInterval interval = [[timer fireDate] timeIntervalSinceReferenceDate];
    NSTimeInterval nextFire = ceil(interval);
    [timer setFireDate: [NSDate dateWithTimeIntervalSinceReferenceDate: nextFire];
    

    然后您将确保计时器在尽可能接近所需时间时触发,并且不必担心计时器滞后,因为它会在每次触发后使用您提供的预期触发日期和间隔自行重置,因此它会总是尝试在精确的第二秒触发(但只要运行循环能够做到这一点就会触发)。

    【讨论】:

      【解决方案3】:

      我不确定还有什么更有效的方法。只要您的计时器回调没有做任何过于密集的事情,您就可能接近最佳状态。

      【讨论】:

        【解决方案4】:

        使用gettimeofday(2)怎么样?它会返回很多准确的时间信息以供使用。

        【讨论】:

        • 不过,这并不能保持显示更新。获取当前时间并不是难事;这是提问者想知道的定期更新。此外,您声称gettimeofday“返回更多[更多] 准确时间信息”缺乏比较:比什么更准确?
        猜你喜欢
        • 2015-09-01
        • 1970-01-01
        • 2017-07-02
        • 2014-08-31
        • 1970-01-01
        • 1970-01-01
        • 2022-07-21
        • 1970-01-01
        • 2018-03-27
        相关资源
        最近更新 更多