iOS中的3種定時器

在iOS中有3種常見的定時器,它們可以根據不同的場景進行選擇使用。
1.DispatchSourceTimer: 基於GCD實現。
2.CADisplayLink:基於屏幕刷新實現。
3.Timer:基於RunLoop實現。

DispatchSourceTimer定時器
DispatchSourceTimer定時器:
可以通過DispatchSource.makeTimerSource(queue: DispatchQueue.main)方法來創建。
然後通過schedule(deadline: .now(), repeating: .seconds(1))方法指定定時器的初始延遲時間和重複時間間隔,
然後設置了一個事件處理程序來處理定時器要執行的操作。
最後調用timer.resume()啓動定時器。
如果停止定時器,可以調用timer.cancel()方法。
優點爲:Dispatch定時器非常輕量級,基於GCD的實現,可以利用GCD的優勢來進行任務調度,性能高。
var timer: DispatchSourceTimer?
func startCountdown() {
    //一般倒計時是操作UI,使用主隊列
    timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
    // //耗時操作放在全局隊列,子線程處理
    // timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
    timer.schedule(deadline: .now(), repeating: .seconds(1))
    timer.setEventHandler {
        // 定時器執行的操作
    }
    timer.resume()
}

deinit {
    timer.cancel()
    timer = nil
}
 
CADisplayLink定時器
CADisplayLink定時器:
可以通過CADisplayLink(target: self, selector: #selector(update))方法創建,
然後通過displayLink.add(to: .main, forMode: .common)方法將定時器添加到主運行循環中,並指定了運行模式,
然後定義一個update處理方法,該方法將在每個定時器週期中執行。
在對象銷燬前停止定時器,可以調用displayLink.invalidate()方法。
它是和屏幕刷新率同步,優點在於精確度高,適用於需要頻繁更新UI的場景。
CADisplayLink對象一旦創建就會運行,比較適合監控主線程UI卡頓。所以用做倒計時得場景下,更好的選擇是使用DispatchSourceTimer定時器。
var displayLink: CADisplayLink?
func startCountdown() {
    //一般倒計時是操作UI,使用主隊列
    let displayLink = CADisplayLink(target: self, selector: #selector(update))
    //設置多長時間回調一次,默認每次刷新都會調用,大概60ps, 這裏設置1表示1s調用一次
    displayLink.preferredFramesPerSecond = 1
    displayLink.add(to: .main, forMode: .common)
}

@objc func update() {
    // 定時器執行的操作
}

deinit {
    displayLink.invalidate()
    displayLink = nil
}
 
Timer定時器
Timer定時器:
可以使用Timer.scheduledTimer方法創建,然後指定重複間隔和一個閉包作爲定時器要執行的操作。
然後將返回的定時器對象存儲在成員變量timer中。
要停止定時器,可以調用timer.invalidate()方法。
Timer是一個簡單的定時器,基於RunLoop的,通常用於實現對實時性要求不高的場合,因爲它被註冊在runloop的timers事件源集合中,如果當前runloop執行耗時任務超過了調用時間,那麼就會丟棄當前次,直接執行下一次。導致定時器不準時的情況。
var timer: Timer?
func startCountdown() {
    //一般倒計時是操作UI,使用主隊列
    timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
    // 定時器執行的操作
    }
}

deinit {
    timer.invalidate()
    timer = nil
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章