JKTimerManager.m 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // JKTimer.m
  3. // JKUtilDemo
  4. //
  5. // Created by Jack on 7/1/16.
  6. // Copyright © 2016 Emerys. All rights reserved.
  7. //
  8. #import "JKTimerManager.h"
  9. #define lockName(var) [NSString stringWithFormat:@"%@_canceller",var]
  10. #define timerLock(var) [[JKTimerManager sharedTimerManager].lockContainer objectForKey:lockName(var)]
  11. @interface JKTimerManager ()
  12. @property (nonatomic,strong) NSMutableDictionary *timerContainer;
  13. @property (nonatomic,strong) NSMutableDictionary *lockContainer;
  14. @end
  15. @implementation JKTimerManager
  16. + (instancetype)sharedTimerManager {
  17. static JKTimerManager *manager = nil;
  18. static dispatch_once_t token;
  19. dispatch_once(&token, ^{
  20. manager = [[JKTimerManager alloc] init];
  21. });
  22. return manager;
  23. }
  24. - (NSMutableDictionary *)timerContainer {
  25. if (!_timerContainer) {
  26. _timerContainer = [NSMutableDictionary dictionary];
  27. }
  28. return _timerContainer;
  29. }
  30. - (void)scheduledDispatchTimerWithName:(NSString *)name
  31. timeInterval:(NSTimeInterval)timerInterval
  32. queue:(dispatch_queue_t)queue
  33. repeats:(BOOL)repeats
  34. action:(dispatch_block_t)action {
  35. if (name == nil)
  36. return;
  37. if (queue == nil)
  38. queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  39. dispatch_source_t timer = [self.timerContainer objectForKey:name];
  40. if (!timer) {
  41. timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
  42. dispatch_resume(timer);
  43. [self.timerContainer setObject:timer forKey:name];
  44. }
  45. NSLock *timer_lock = [[NSLock alloc] init];
  46. [self.lockContainer setObject:timer_lock forKey:lockName(name)];
  47. dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, timerInterval * NSEC_PER_SEC), timerInterval * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
  48. __weak typeof(self) weakSelf = self;
  49. dispatch_source_set_event_handler(timer, ^{
  50. [timerLock(name) lock];
  51. if (timer && action) {
  52. action();
  53. if (!repeats) {
  54. [weakSelf cancelTimerWithName:name];
  55. }
  56. }
  57. [timerLock(name) unlock];
  58. });
  59. }
  60. - (void)cancelTimerWithName:(NSString *)name {
  61. dispatch_source_t timer = [self.timerContainer objectForKey:name];
  62. if (!timer) {
  63. return;
  64. }
  65. NSLock *timer_lock = timerLock(name);
  66. [timer_lock lock];
  67. [self.lockContainer removeObjectForKey:lockName(name)];
  68. [self.timerContainer removeObjectForKey:name];
  69. dispatch_source_cancel(timer);
  70. timer = nil;
  71. [timer_lock unlock];
  72. }
  73. - (void)cancelAllTimer {
  74. for (NSString *name in self.timerContainer.allKeys) {
  75. [self cancelTimerWithName:name];
  76. }
  77. }
  78. @end