gpt4 book ai didi

ios - 使用计时器时 UI 滞后

转载 作者:行者123 更新时间:2023-11-28 07:52:12 25 4
gpt4 key购买 nike

我正在使用每秒重复一次的计时器来更新正在播放的 currentPlaybackTime,因此我每秒都会用当前歌曲的进度更新我的标签。我曾经使用 NSTimer 或在 Swift 中使用 Timer 来每秒重复一次,但是在更改歌曲或开始和停止歌曲时我遇到了问题秒标签会滞后(它会保持不变 5 秒钟,当您听到歌曲播放时,然后会更新到正确的时间)。然后我继续使用 GCD,我遇到了同样的问题,即使是在后台队列上。然后我去使用 DispatchSourceTimer,我得到了以下日志:

Fired: 2018-03-18 13:22:17 +0000
Timer fired: 2018-03-18 13:22:17 +0000
Fired: 2018-03-18 13:22:18 +0000
Timer fired: 2018-03-18 13:22:18 +0000
Fired: 2018-03-18 13:22:19 +0000
Fired: 2018-03-18 13:22:20 +0000
Timer fired: 2018-03-18 13:22:20 +0000
Fired: 2018-03-18 13:22:21 +0000
Fired: 2018-03-18 13:22:22 +0000
Fired: 2018-03-18 13:22:23 +0000
Fired: 2018-03-18 13:22:24 +0000
Fired: 2018-03-18 13:22:25 +0000
Fired: 2018-03-18 13:22:26 +0000
Fired: 2018-03-18 13:22:27 +0000
Fired: 2018-03-18 13:22:28 +0000
Fired: 2018-03-18 13:22:29 +0000
Fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Timer fired: 2018-03-18 13:22:30 +0000
Fired: 2018-03-18 13:22:31 +0000
Timer fired: 2018-03-18 13:22:31 +0000
Fired: 2018-03-18 13:22:32 +0000
Timer fired: 2018-03-18 13:22:32 +0000

显示“Fired”的是 DispatchSourceTimer 的实际偶数处理程序,而“Timer Fired”在更新标签等的处理函数中。很明显你可以看到计时器工作正常,但似乎主线程被大量使用。

这是我的代码:

//timer is a DispatchSourceTimer, queue is a concurrent custom queue
public func startTimer() {
timer?.cancel()
timer = DispatchSource.makeTimerSource(queue: queue)
timer?.schedule(deadline: DispatchTime.now(), repeating: .seconds(1))
timer?.setEventHandler { [weak self] in
print("Fired: \(Date())")
DispatchQueue.main.async {
self?.notifyObservers()
}
}
timer?.resume()
}

public func stopTimer() {
timer?.cancel()
timer = nil
}

这里是通知观察者:

private func notifyObservers() {
for observer: TimeObserver in self.timeObservers {
observer.timerFired()
}
}

我维护了一个对象的观察者数组,这些对象希望收到定时器触发的通知。

我做了一个测试,删除了 for 循环,只通知了列表中的第一个观察者,它确实加快了速度,但仍然没有解决问题。

如果我只是播放这首歌,几秒钟后主线程实际上可以处理它并且我可以完美地显示时间,但是当做一些繁重的事情时,比如使用 MPMediaPlayer 框架来改变一首歌或者在 MPMusicPlayerController 上调用 play()pause() 时,它开始滞后。

如有任何帮助,我们将不胜感激。谢谢。

最佳答案

如果您像这样实例化您的播放器,您会看到这种行为:

let player = MPMusicPlayerController()

但是如果您使用:

let player = MPMusicPlayerController.applicationQueuePlayer

或:

let player = MPMusicPlayerController.applicationMusicPlayer

在我的 iPhone X 上,使用前一种技术时,我的主线程阻塞了 5-8 秒,但使用后两种技术时,只有一秒或更短的时间。


我假设您的调度计时器是为了测试正在发生的事情,但是如果它要做的只是将它调度回主队列,那么在后台线程上使用这个调度计时器是没有意义的。如果您的主线程由于您无法控制的原因而被阻塞,您不希望在主线程中积压一堆无法及时处理的更新。

我建议恢复到简单的 Timer

关于ios - 使用计时器时 UI 滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49348448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com