为什么“scheduledTimer”会在块外部设置时触发,但不在块内?

下面的代码片段在完成块之外被调用时是完美的,但是当我在块内部设置时,定时器永远不会被触发。 我不明白为什么有一个区别:

self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.foo), userInfo: nil, repeats: true) 

最初在块外面调用它时,我并没有使用自引用,但是一旦进入,它就是必需的。 不过,我再次testing了完全相同的代码,它仍然工作。

该块是一个完成HealthKit在询问对HealthKit相关信息的许可后调用。

问题是,有问题的完成块可能没有在主线程上运行,因此没有运行循环。 但是定时器需要在运行循环中进行调度,而在主线程有一个时,大多数后台线程不会(除非你自己添加一个)。

为了解决这个问题,在完成处理程序中,将计时器的创build分派回主线程,并且应该可以正常工作:

 DispatchQueue.main.async { self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true) } 

或者使用一个调度源定时器(一个可以调度为后台队列的定时器,不需要运行循环)。

 var timer: DispatchSourceTimer! func startTimer() { let queue = DispatchQueue(label: "com.domain.app.timer") timer = DispatchSource.timer(queue: queue) timer.setEventHandler { [weak self] in // do something } timer.scheduleRepeating(deadline: .now(), interval: 1.0) timer.resume() }