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
网友评论