GCDTimer.m 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //
  2. // GCDTimer.m
  3. // Temperature
  4. //
  5. // Created by RD on 2023/1/10.
  6. //
  7. #import "GCDTimer.h"
  8. typedef enum : NSUInteger {
  9. Status_Running,
  10. Status_Pause,
  11. Status_Cancle,
  12. } TimerStatus;
  13. @interface GCDTimer ()
  14. @property (nonatomic, strong) dispatch_source_t gcdTimer;
  15. @property (nonatomic, assign) TimerStatus currentStatus;
  16. @property (nonatomic, assign) NSTimeInterval interval;
  17. @end
  18. @implementation GCDTimer
  19. - (void)scheduledTimerWithTimeInterval:(NSTimeInterval)interval afterTime:(NSTimeInterval)afterTime repeats:(BOOL)repeats block:(void (^)(void))block {
  20. self.interval = interval;
  21. __weak typeof(self) wself = self;
  22. /** 创建定时器对象 dispatch_source_create
  23. * para1: DISPATCH_SOURCE_TYPE_TIMER 为定时器类型
  24. * para2-3: 中间两个参数对定时器无用
  25. * para4: queue 最后为在什么调度队列中使用
  26. */
  27. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  28. self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
  29. /** 设置定时器 dispatch_source_set_timer
  30. * para1: timer 定时器
  31. * para2: when 任务开始时间
  32. * para3: interval 任务的间隔
  33. * para4: 可接受的误差时间,设置0即不允许出现误差
  34. * Tips: 单位均为纳秒
  35. */
  36. dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, afterTime * NSEC_PER_SEC);
  37. dispatch_source_set_timer(self.gcdTimer, when, interval * NSEC_PER_SEC, 1);
  38. dispatch_source_set_event_handler(self.gcdTimer, ^{
  39. if (!repeats) {
  40. dispatch_source_cancel(wself.gcdTimer);
  41. }
  42. block();
  43. });
  44. dispatch_resume(self.gcdTimer);
  45. self.currentStatus = Status_Running;
  46. }
  47. // 暂停
  48. - (void)pauseTimer {
  49. if (self.currentStatus == Status_Running && self.gcdTimer) {
  50. dispatch_suspend(self.gcdTimer);
  51. self.currentStatus = Status_Pause;
  52. }
  53. }
  54. // 开始
  55. - (void)resumeTimer {
  56. if (self.currentStatus == Status_Pause && self.gcdTimer) {
  57. dispatch_resume(self.gcdTimer);
  58. self.currentStatus = Status_Running;
  59. }
  60. }
  61. // 重新开始
  62. - (void)restartTimer{
  63. [self pauseTimer];
  64. // *秒后重新开始执行
  65. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  66. [self resumeTimer];
  67. });
  68. }
  69. // 取消
  70. - (void)stopTimer {
  71. if (self.gcdTimer) {
  72. // 暂停的时候不能直接取消
  73. if (self.currentStatus == Status_Pause){
  74. [self resumeTimer];
  75. }
  76. dispatch_source_cancel(self.gcdTimer);
  77. self.currentStatus = Status_Cancle;
  78. self.gcdTimer = nil;
  79. }
  80. }
  81. @end