美文网首页
GCD定时器的封装

GCD定时器的封装

作者: Jean_Lina | 来源:发表于2020-10-28 10:29 被阅读0次
static NSMutableDictionary *timerDictionary;
dispatch_semaphore_t semaphore;

@implementation GCDTimer
#pragma mark 数据初始化
+ (void)initialize
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timerDictionary = [NSMutableDictionary dictionary];
        semaphore = dispatch_semaphore_create(1);
    });
}
#pragma mark 执行定时器任务
+ (NSString *)execTask:(void(^)(void))task start:(NSTimeInterval)start interval:(NSTimeInterval)interval async:(BOOL)async repeat:(BOOL)repeat {
    if (task == nil || start < 0 || (repeat && interval <= 0)) {
        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, (int64_t)(start * NSEC_PER_SEC)), (uint64_t)(interval * NSEC_PER_SEC), 0);
    //保证数据读写安全
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSString *name = [NSString stringWithFormat:@"%lu", (unsigned long)timerDictionary.count];
    timerDictionary[name] = timer;
    dispatch_semaphore_signal(semaphore);
    
    //设置回调
    dispatch_source_set_event_handler(timer, ^{
        task();
        if (!repeat) {
            [self cancelTask:name];
        }
        
    });
    //启动定时器
    dispatch_resume(timer);
    return name;
}
#pragma mark 取消定时器任务
+ (void)cancelTask:(NSString *)name {
    if (name.length == 0) {
        return;
    }
    //保证数据读写安全
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_source_t timer = timerDictionary[name];
    if (timer) {
        dispatch_source_cancel(timerDictionary[name]);
        [timerDictionary removeObjectForKey:name];
    }
    dispatch_semaphore_signal(semaphore);
}
#pragma mark 处理定时器任务
+ (NSString *)doTask:(id)target selector:(SEL)selector start:(NSTimeInterval)start interval:(NSTimeInterval)interval async:(BOOL)async repeat:(BOOL)repeat {
    if (target == nil || selector == nil) {
        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 async:async repeat:repeat];
}
@end

相关文章

网友评论

      本文标题:GCD定时器的封装

      本文链接:https://www.haomeiwen.com/subject/plbxvktx.html