關(guān)于 DispatchSourceTimer 的使用

在網(wǎng)上找到的一個比較好的封裝, 自己再進行了一些處理, 保證啟動和停止是線程安全的.

public protocol BackgroundTimer {
    func resume()
    func suspend()
}

public class BackgroundTimerMaker {
    public static func makeTimer(adding: TimeInterval, task: (()->())?) -> BackgroundTimer {
        return BackgroundTimerImp(deadline: .now() + adding, repeating: .never, task: task)
    }

    public static func makeTimer(adding: TimeInterval, repeatInterval: Int, task: (()->())?) -> BackgroundTimer {
        return BackgroundTimerImp(deadline: .now() + adding, repeating: .seconds(repeatInterval), task: task)
    }

    public static func makeTimer(repeatInterval: Int, task: (()->())?) -> BackgroundTimer {
        return BackgroundTimerImp(deadline: .now(), repeating: .seconds(repeatInterval), task: task)
    }
}

class BackgroundTimerImp: BackgroundTimer {

    private var task: (()->())?

    private let _timer: DispatchSourceTimer

    private let _lock = NSLock()

    private enum State {
        case suspended
        case resumed
    }

    private var state: State = .suspended

    init(deadline: DispatchTime, repeating: DispatchTimeInterval = .never,
         leeway: DispatchTimeInterval = .milliseconds(100), task: (()->())?) {
        self.task = task
        _timer = DispatchSource.makeTimerSource()
        _timer.schedule(deadline: deadline,
                        repeating: repeating,
                        leeway: leeway)
        _timer.setEventHandler(handler: {
            task?()
        })
    }

    func resume() {
        guard state != .resumed else { return }
        _lock.lock()
        defer {
            _lock.unlock()
        }
        guard state != .resumed else { return }
        state = .resumed
        _timer.resume()
    }

    func suspend() {
        guard state != .suspended else { return }
        _lock.lock()
        defer {
            _lock.unlock()
        }
        guard state != .suspended else { return }
        state = .suspended
        _timer.suspend()
    }

    deinit {
        _timer.setEventHandler {}
        task = nil
        print("deinit timer source")
    }
}

用法:

  1. 創(chuàng)建并持有 timer(如果沒有被其他對象持有, 則會被釋放掉)
  2. 要開始計時, 調(diào)用 timer 的 resume 方法.
  3. 要停止計時, 調(diào)用 timer 的 suspend 方法.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容