swift - 使用计时器更新时间时如何使时间与 macOS 系统时钟同步?
问题描述
我正在使用此代码在 NSLabel 中显示时间:
模型
func startClock() {
timer = Timer(timeInterval: 1.0, target: self, selector: #selector(fireAction), userInfo: nil, repeats: true)
RunLoop.current.add(timer!, forMode: RunLoop.Mode.common)
timer?.tolerance = 0.05
fireAction()
}
@objc dynamic func fireAction() {
delegate?.timeToUpdateClock(self)
}
视图控制器
extension ViewController: ClockWorksProtocol {
func timeToUpdateClock(_ timer: ClockWorks) {
tick()
}
}
func tick() {
clockDateLabel.stringValue = DateFormatter.localizedString(from: Date(), dateStyle: .full, timeStyle: .none)
clockTimeLabel.stringValue = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .medium)
}
一切似乎都运行良好,但不幸的是,显示的秒数与您在菜单栏上的时钟中看到的秒数不同步。我认为会发生这种情况,因为我每秒都会更新时钟,但用户不会在第二秒正确开始时单击,而是在从一秒到下一秒的随意间隔内单击(我使用 timeInterval 作为 1.0 的计时器) .
我可以将计时器的 timeInterval 从 1.0 秒更改为 0.1 秒。这似乎可行,但我担心这可能会消耗太多资源。
我发布了两个同时制作的屏幕截图。它们显示两个不同的时间(秒):
我该如何解决这个差距?
解决方案
我知道您可以在这里采取两种方法:
- 计算
dt
从现在到下一秒之间的时间量。
let nextSecond = floor(now.timeIntervalSince1970) + 1
let dt = nextSecond - now.timeIntervalSince1970
dt
制作一个从现在开始精确触发一次的计时器。在该计时器的回调中,启动一个以 1 秒间隔重复的计时器(tick()
每次执行),这正是您的startClock()
函数所做的。
tick()
如果您希望滴答声尽快开始,您也可以在第一个计时器触发时运行。
- 确定下一秒发生的时刻作为日期。
Date(timeIntervalSince1970: floor(Date().timeIntervalSince1970) + 1)
将此初始化用于在特定fireAt
日期启动它的计时器,将其设置为每秒重复一次。
let timer = Timer(fireAt:
Date(timeIntervalSince1970:
floor(Date().timeIntervalSince1970) + 1),
interval: 1.0,
target: self,
selector: #selector(fireAction),
userInfo: nil,
repeats: true)
推荐阅读
- asp.net-core - Ubuntu 20.04 上的身份脚手架使用不正确的文件路径 dotnet 5
- c# - 有没有更有效的方法在我的数据库中插入数据数组?Asp.net-core + Dapper
- mysql - 图像未插入 MySQL。错误 1048
- c++ - 宽松的内存顺序自旋锁总是会破坏同步吗?
- rxjs - 在这种情况下,如何使用 rxjs Observable 抛出错误?
- c++ - 无法在 C++ 向量中调用擦除()操作
> - c# - C# EventHandler 文档代码示例
- python - 如何使用 python tkinter 将所选图像上传到标签中?
- python - 在 Selenium/Python 中从亚马逊产品页面的图像中提取所有 src 属性
- python - TypeError:需要一个整数(获取类型元组)|| python中的网站阻止代码