一个 DispatchTimer 的使用示例

本文最后更新于 2021年4月4日 晚上

这里介绍一种更加轻量级的 Timer 实现, 适用于各种需要 Timer 的场景.

DispatchTimer 的使用

在这里封装一个用于后台线程中的计时器,如下所示:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
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()
guard state != .resumed else { return }
state = .resumed
_timer.resume()
defer {
_lock.unlock()
}
}

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

deinit {
// 注意: 这里必须这样写, 否则在释放 timer 的时候会发生崩溃

_timer.setEventHandler {}
_timer.cancel()
resume()
task = nil
}
}

一个 DispatchTimer 的使用示例
https://blog.rayy.top/2018/09/11/2019-AboutDispatchTimer/
作者
貘鸣
发布于
2018年9月11日
许可协议