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.setEventHandler {} _timer.cancel() resume() task = nil } }
|