以下代码片段在完成块外部调用时工作正常,但是当我在块内部设置它时,定时器永远不会被触发.我不明白为什么会有区别:
self.timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(self.foo),
userInfo: nil,
repeats: true)
Run Code Online (Sandbox Code Playgroud)
我最初在块外调用它时没有使用自引用,但是一旦进入内部,就需要它.但是我再次在块外测试完全相同的代码,它仍然可以工作.
该块是完成处理程序,在请求HealthKit
相关信息的许可后调用.
Rob*_*Rob 54
问题是有问题的完成块可能没有在主线程上运行,因此没有运行循环.但是定时器需要在运行循环上进行调度,而主线程有一个,大多数后台线程都没有(除非你自己添加一个).
为了解决这个问题,在该完成处理程序中,将计时器的创建发送回主线程,它应该可以正常工作:
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)
}
Run Code Online (Sandbox Code Playgroud)
或者使用调度源计时器(可以为后台队列调度的计时器,不需要运行循环).
var timer: DispatchSourceTimer!
private func startTimer() {
let queue = DispatchQueue(label: "com.domain.app.timer")
timer = DispatchSource.makeTimerSource(queue: queue)
timer.setEventHandler { [weak self] in
// do something
}
timer.schedule(deadline: .now(), repeating: 1.0)
timer.resume()
}
Run Code Online (Sandbox Code Playgroud)
有关早期版本Swift的语法,请参阅此答案的上一版本.
Timer() 可能不起作用的另一个原因是它的创建方式。我遇到了同样的问题,我尝试的所有方法都没有解决它,包括在主线程上实例化。我盯着这个看了很长时间,直到我意识到(愚蠢地)我正在以不同的方式创造它。代替Timer.scheduledTimer
我实例化它使用
let timer = Timer(timeInterval: 4.0, target: self, selector: #selector(self.timerCompletion), userInfo: nil, repeats: true)
Run Code Online (Sandbox Code Playgroud)
就我而言,我必须将它实际添加到运行循环中才能运行。像这样
RunLoop.main.add(timer, forMode: RunLoop.Mode.default)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2593 次 |
最近记录: |