// // GCDTimer.m // Temperature // // Created by RD on 2023/1/10. // #import "GCDTimer.h" typedef enum : NSUInteger { Status_Running, Status_Pause, Status_Cancle, } TimerStatus; @interface GCDTimer () @property (nonatomic, strong) dispatch_source_t gcdTimer; @property (nonatomic, assign) TimerStatus currentStatus; @property (nonatomic, assign) NSTimeInterval interval; @end @implementation GCDTimer - (void)scheduledTimerWithTimeInterval:(NSTimeInterval)interval afterTime:(NSTimeInterval)afterTime repeats:(BOOL)repeats block:(void (^)(void))block { self.interval = interval; __weak typeof(self) wself = self; /** 创建定时器对象 dispatch_source_create * para1: DISPATCH_SOURCE_TYPE_TIMER 为定时器类型 * para2-3: 中间两个参数对定时器无用 * para4: queue 最后为在什么调度队列中使用 */ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); /** 设置定时器 dispatch_source_set_timer * para1: timer 定时器 * para2: when 任务开始时间 * para3: interval 任务的间隔 * para4: 可接受的误差时间,设置0即不允许出现误差 * Tips: 单位均为纳秒 */ dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, afterTime * NSEC_PER_SEC); dispatch_source_set_timer(self.gcdTimer, when, interval * NSEC_PER_SEC, 1); dispatch_source_set_event_handler(self.gcdTimer, ^{ if (!repeats) { dispatch_source_cancel(wself.gcdTimer); } block(); }); dispatch_resume(self.gcdTimer); self.currentStatus = Status_Running; } // 暂停 - (void)pauseTimer { if (self.currentStatus == Status_Running && self.gcdTimer) { dispatch_suspend(self.gcdTimer); self.currentStatus = Status_Pause; } } // 开始 - (void)resumeTimer { if (self.currentStatus == Status_Pause && self.gcdTimer) { dispatch_resume(self.gcdTimer); self.currentStatus = Status_Running; } } // 重新开始 - (void)restartTimer{ [self pauseTimer]; // *秒后重新开始执行 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self resumeTimer]; }); } // 取消 - (void)stopTimer { if (self.gcdTimer) { // 暂停的时候不能直接取消 if (self.currentStatus == Status_Pause){ [self resumeTimer]; } dispatch_source_cancel(self.gcdTimer); self.currentStatus = Status_Cancle; self.gcdTimer = nil; } } @end