開發過程中,我們可能會經常使用到計時器。蘋果為我們提供了Timer。但是在平時使用過程中會發現使用Timer會有許多的不便
1:必須保證在一個活躍的runloop,我們知道主線程的runloop是活躍的,但是在其他異步線程runloop就需要我們自己去開啟,非常麻煩。
2:Timer的創建和銷毀必須在同一個線程??缇€程就操作不了
3:內存問題??赡苎h引用造成內存泄露
由于存在上述問題,我們可以采用GCD封裝來解決。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
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 } } |
使用方法
1
2
3
4
|
MRGCDTimer.share.scheduledDispatchTimer(withName: "name" , timeInterval: 1, queue: .main, repeats: true ) { //code self.updateCounter() } |
取消計時器
1
|
MRGCDTimer.share.destoryTimer(withName: "name" ) |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/weixin_42779997/article/details/88173588