Swift4使用GCD實現計時器
阿新 • • 發佈:2020-03-04
開發過程中,我們可能會經常使用到計時器。蘋果為我們提供了Timer。但是在平時使用過程中會發現使用Timer會有許多的不便
1:必須保證在一個活躍的runloop,我們知道主執行緒的runloop是活躍的,但是在其他非同步執行緒runloop就需要我們自己去開啟,非常麻煩。
2:Timer的建立和銷燬必須在同一個執行緒。跨執行緒就操作不了
3:記憶體問題。可能迴圈引用造成記憶體洩露
由於存在上述問題,我們可以採用GCD封裝來解決。
import UIKit typealias ActionBlock = () -> () class MRGCDTimer: NSObject { static let share = MRGCDTimer() lazy var timerContainer = [String : DispatchSourceTimer]() /// 建立一個名字為name的定時 /// /// - Parameters: /// - name: 定時器的名字 /// - timeInterval: 時間間隔 /// - queue: 執行緒 /// - repeats: 是否重複 /// - action: 執行的操作 func scheduledDispatchTimer(withName name:String?,timeInterval:Double,queue:DispatchQueue,repeats:Bool,action:@escaping ActionBlock ) { if name == nil { return } var timer = timerContainer[name!] if timer==nil { timer = DispatchSource.makeTimerSource(flags: [],queue: queue) timer?.resume() timerContainer[name!] = timer } timer?.schedule(deadline: .now(),repeating: timeInterval,leeway: .milliseconds(100)) timer?.setEventHandler(handler: { [weak self] in action() if repeats==false { self?.destoryTimer(withName: name!) } }) } /// 銷燬名字為name的計時器 /// /// - Parameter name: 計時器的名字 func destoryTimer(withName name:String?) { let timer = timerContainer[name!] if timer == nil { return } timerContainer.removeValue(forKey: name!) timer?.cancel() } /// 檢測是否已經存在名字為name的計時器 /// /// - Parameter name: 計時器的名字 /// - Returns: 返回bool值 func isExistTimer(withName name:String?) -> Bool { if timerContainer[name!] != nil { return true } return false } }
使用方法
MRGCDTimer.share.scheduledDispatchTimer(withName: "name",timeInterval: 1,queue: .main,repeats: true) { //code self.updateCounter() }
取消計時器
MRGCDTimer.share.destoryTimer(withName: "name")
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。