swift - MacOS 上最准确的计时器

标签 swift macos grand-central-dispatch nstimer

我有一个应用程序可以从连接到 Mac 的 USB 传感器读取环境数据。用户能够配置应用程序对数据进行采样的频率以及应用程序对这些样本进行平均并将平均值记录到文件中的频率。

我第一次使用 NSTimer 但那非常不准确,尤其是当显示器进入休眠状态时。我现在正在使用 DispatchSourceTimer,但它仍然大约每 21-23 秒损失 1 毫秒,大约每 6 小时左右损失 1 秒。我希望每天的时间少于 1 秒。

我有什么想法可以让计时器更准确一点吗?

func setupTimer() -> DispatchSourceTimer {
    let timer = DispatchSource.makeTimerSource(flags: .strict, queue: nil)
    let repeatInterval = DispatchTimeInterval.seconds(samplingInterval)
    let deadline : DispatchTime = .now() + repeatInterval
    timer.schedule(deadline: deadline, repeating: repeatInterval, leeway: .nanoseconds(0))
    timer.setEventHandler(handler: self.collectPlotAndLogDatapoint)
    return timer
}

func collectPlotAndLogDatapoint() {
    samplingIntervalCount += 1
    let dataPoint : Float = softwareLoggingDelegate?.getCurrentCalibratedOutput() ?? 0
    accumulatedTotal += dataPoint
    if samplingIntervalCount == loggingInterval / samplingInterval{
        let average = self.accumulatedTotal/Float(self.samplingIntervalCount)
        DispatchQueue.global().async {
            self.logDataPoint(data: average)
            self.chartControls.addPointsToLineChart([Double(average)], Date().timeIntervalSince1970)
            self.samplingIntervalCount = 0
            self.accumulatedTotal = 0
        }
    }
}

最佳答案

对此的回答(以及回应的评论)似乎表明在 Swift 中很难获得亚毫秒级的精度:

How do I achieve very accurate timing in Swift?

Apple 显然对高精度计时器有自己的注意事项:https://developer.apple.com/library/archive/technotes/tn2169/_index.html

对于环境传感器来说,每天大约 3-4 秒是相当准确的,我想这只会证明对于那些想要以 << 1 秒的间隔进行采样的用户来说是一个问题(甚至是值得注意的)。

关于swift - MacOS 上最准确的计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53397513/

相关文章:

swift - 如何在 OS X 目标中创建 CFDictionary?

cocoa - 在系统范围内更改 cocoa 单词补全 - 可能吗?

macos - Mac 上的软件开发

swift - 有没有办法取消 DispatchQueue concurrentPerform 操作?

ios - 使用 Blocks 和 GCD 管理任务

ios - Swift 4 NSLayoutConstraint 无法正常工作

swift - 如何使用 NSNotification 将 sqlite.swift 的 Row 传递到另一个 Controller

macos - 对框架进行代码签名失败,出现 "Permission denied"错误

swift - 在 Swift 中的 Dispatch 闭包中修改结构实例变量

ios - 在许多 View Controller 上使用委托(delegate)和协议(protocol)快速更改主题