定义一个全局计时器,延迟执行操作。可以对计时器进行全局控制,能手动控制暂停/重启/停止,并在计时结束后释放掉计时器。
import Foundation
class TimerManager {
static let shared = TimerManager()
private var timer: DispatchSourceTimer?
private var isTimerSuspended = false
private init() {}
func startTimer(delay: TimeInterval, completion: @escaping () -> Void) {
let queue = DispatchQueue(label: "com.timermanager.queue")
timer?.cancel() // Cancel any existing timer before starting a new one
timer = DispatchSource.makeTimerSource(queue: queue)
timer?.schedule(deadline: .now() + delay)
timer?.setEventHandler(handler: { [weak self] in
completion()
self?.stopTimer()
})
isTimerSuspended = false
timer?.resume()
}
func pauseTimer() {
guard !isTimerSuspended, let timer = timer else { return }
timer.suspend()
isTimerSuspended = true
}
func resumeTimer() {
guard isTimerSuspended, let timer = timer else { return }
timer.resume()
isTimerSuspended = false
}
func stopTimer() {
guard let timer = timer else { return }
timer.cancel()
self.timer = nil
isTimerSuspended = false
}
}
使用TimerManager:
// 启动定时器,10秒后执行操作
TimerManager.shared.startTimer(delay: 10) {
print("Timer fired!")
}
// 暂停定时器
TimerManager.shared.pauseTimer()
// 一段时间后...
// 恢复定时器
TimerManager.shared.resumeTimer()
// 如果需要停止定时器,释放资源
TimerManager.shared.stopTimer()
这种全局计时器,我们经常会用到。比如需要延迟10秒弹出系统好评弹窗,但又不希望在“订阅页”弹窗。这时我们进入“订阅页”时就要暂停定时器,离开“订阅页”时再恢复计时。