我正在使用以下代码在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)
}
ViewController
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秒。这似乎可行,但恐怕这会浪费太多资源。
我发布了同时制作的两个屏幕截图。它们显示两个不同的时间(秒):
我如何解决差距?
答案 0 :(得分:0)
我知道您可以在这里采取两种方法:
dt
。let nextSecond = floor(now.timeIntervalSince1970) + 1
let dt = nextSecond - now.timeIntervalSince1970
制作一个计时器,从现在开始正好触发一次 dt
。在该计时器的回调中,启动一个以 1 秒为间隔重复的计时器(每次执行 tick()
),这正是您的 startClock()
函数所做的。
如果您希望滴答声尽快开始,您也可以在第一个计时器触发时运行 tick()
。
Date(timeIntervalSince1970: floor(Date().timeIntervalSince1970) + 1)
将此 init 用于计时器,它在特定的 fireAt
日期启动它,将其设置为每秒重复一次。
let timer = Timer(fireAt:
Date(timeIntervalSince1970:
floor(Date().timeIntervalSince1970) + 1),
interval: 1.0,
target: self,
selector: #selector(fireAction),
userInfo: nil,
repeats: true)