众所周知,NSTimer 因为依赖于RunLoop去执行,而RunLoop本身工作很繁重,不能确保Timer及时执行,所以使用GCD Timer会更加准时,使用起来也不难,我封装了一个类,供大家参考。
public protocol SPTimer {
// 启动
func resume()
// 暂停
func suspend()
// 取消
func cancel()
}
class SPTimerMaker {
static func exec(_ task: (() -> ())?, interval: Int, repeats: Bool = true, async: Bool = true) -> SPTimer? {
guard let _ = task else {
return nil
}
return TimerMaker(task,
deadline: .now(),
repeating: repeats ? .seconds(interval):.never,
async: async)
}
}
private class TimerMaker: SPTimer {
/// 当前Timer 运行状态
enum TimerState {
case runing
case stoped
}
private var state = TimerState.stoped
private var timer: DispatchSourceTimer?
convenience init(_ exce: (() -> ())?, deadline: DispatchTime, repeating interval: DispatchTimeInterval = .never, leeway: DispatchTimeInterval = .seconds(0), async: Bool = true) {
self.init()
let queue = async ? DispatchQueue.global():DispatchQueue.main
timer = DispatchSource.makeTimerSource(queue: queue)
timer?.schedule(deadline: deadline,
repeating: interval,
leeway: leeway)
timer?.setEventHandler(handler: {
exce?()
})
}
func resume() {
guard state != .runing else { return }
state = .runing
timer?.resume()
}
func suspend() {
guard state != .stoped else { return }
state = .stoped
timer?.suspend()
}
func cancel() {
state = .stoped
timer?.cancel()
}
}