123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- //
- // SLTimer.m
- //
- // Created by wsl on 2020/6/15.
- // Copyright © 2020 https://github.com/wsl2ls ----- . All rights reserved.
- //
- #import "SLTimer.h"
- @implementation SLTimer
- static NSMutableDictionary *timers_;
- dispatch_semaphore_t semaphore_;
- + (void)initialize
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- timers_ = [NSMutableDictionary dictionary];
- semaphore_ = dispatch_semaphore_create(1);
- });
- }
- + (NSString *)execTask:(void (^)(void))task start:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats async:(BOOL)async
- {
- if (!task || start < 0 || (interval <= 0 && repeats)) return nil;
-
- // 队列
- dispatch_queue_t queue = async ? dispatch_get_global_queue(0, 0) : dispatch_get_main_queue();
-
- // 创建定时器
- dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
-
- // 设置时间
- dispatch_source_set_timer(timer,
- dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC),
- interval * NSEC_PER_SEC, 0);
-
-
- dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER);
- // 定时器的唯一标识
- NSString *name = [NSString stringWithFormat:@"%zd", timers_.count];
- // 存放到字典中
- timers_[name] = timer;
- dispatch_semaphore_signal(semaphore_);
-
- // 设置回调
- dispatch_source_set_event_handler(timer, ^{
- task();
-
- if (!repeats) { // 不重复的任务
- [self cancelTask:name];
- }
- });
-
- // 启动定时器
- dispatch_resume(timer);
-
- return name;
- }
- + (NSString *)execTask:(id)target selector:(SEL)selector start:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats async:(BOOL)async
- {
- if (!target || !selector) return nil;
-
- return [self execTask:^{
- if ([target respondsToSelector:selector]) {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- [target performSelector:selector];
- #pragma clang diagnostic pop
- }
- } start:start interval:interval repeats:repeats async:async];
- }
- + (void)cancelTask:(NSString *)taskName;
- {
- if (taskName.length == 0) return;
-
- dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER);
-
- dispatch_source_t timer = timers_[taskName];
- if (timer) {
- dispatch_source_cancel(timer);
- [timers_ removeObjectForKey:taskName];
- }
-
- dispatch_semaphore_signal(semaphore_);
- }
- @end
|