其实定时器我们有很多创建形式 NSTimer、GCD等,今天我来说一下GCD版本的定时器
首先,什么是GCD呢?
百度一查一大堆
Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。
它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。
它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。
为什么使用GCD呢?
因为使用 GCD 有很多优势
1、GCD 可用于多核的并行运算;
2、GCD 会自动利用更多的 CPU 内核(比如双核、四核);
3、GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程);
4、程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码。
下面就是干活儿了,直接上代码(这里我们把定时器封装了一个类、SXGCDTimer类,方便使用)
.h文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface SXGCDTimer : NSObject
/// 创建定时器
/// @param start 延迟多久执行
/// @param interval 多久时间执行一次
/// @param repeats 是否重复
/// @param async 是否是主线成
/// @param completion 执行方法
+ (NSString *)timerWithStartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async completion:(void (^)(void))completion;
/// 创建定时器
/// @param target 当前累
/// @param selector 执行的方法
/// @param start 延迟多久执行
/// @param interval 时间间隔
/// @param repeats 是否重复
/// @param async 是否主主线程
+ (NSString *)timerWithTarget:(id)target selector:(SEL)selector StartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async;
/// 取消某个定时器,
/// @param timerID 定时器id,默认从1开始,每创建一个定时器 +1
+ (void)cancel:(NSString *)timerID;
@end
.m
//
// SXGCDTimer.m
// SamsungSecurity
//
// Created by abox on 2020/12/17.
// Copyright © 2020 abox. All rights reserved.
//
#import "SXGCDTimer.h"
@interface SXGCDTimer()
@end
@implementation SXGCDTimer
static int i = 0;
// 创建保存timer的容器
static NSMutableDictionary *timers;
dispatch_semaphore_t sem;
+ (void)initialize{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
timers = [NSMutableDictionary dictionary];
sem = dispatch_semaphore_create(1);
});
}
/// 创建定时器
/// @param target 当前累
/// @param selector 执行的方法
/// @param start 延迟多久执行
/// @param interval 时间间隔
/// @param repeats 是否重复
/// @param async 是否主主线程
+ (NSString *)timerWithTarget:(id)target selector:(SEL)selector StartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async{
if (!target || !selector) {
return nil;
}
return [self timerWithStartTime:start interval:interval repeats:repeats mainQueue:async completion:^{
if ([target respondsToSelector:selector]) {
[target performSelector:selector];
}
}];
}
/// 创建定时器
/// @param start 延迟多久执行
/// @param interval 多久时间执行一次
/// @param repeats 是否重复
/// @param async 是否是主线成
/// @param completion 执行方法
+ (NSString *)timerWithStartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async completion:(void (^)(void))completion{
if (!completion || start < 0 || interval <= 0) {
return nil;
}
// 创建定时器
dispatch_queue_t queue = !async ? dispatch_queue_create("gcd.timer.queue", NULL) : dispatch_get_main_queue();
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue );
// 设置时间,从什么时候开始,间隔多少,下面相当于2s后开始,每隔一秒一次
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0);
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
NSString *timerId = [NSString stringWithFormat:@"%d",i++];
NSLog(@"timerId = = = = = =%@",timerId);
timers[timerId]=timer;
dispatch_semaphore_signal(sem);
// 回调
dispatch_source_set_event_handler(timer, ^{
if (completion) {
completion();
}
// 不重复执行就取消timer
if (!repeats) {
[self cancel:timerId];
}
});
dispatch_resume(timer);
return timerId;
}
/// 取消某个定时器,
/// @param timerID 定时器id,默认从1开始,每创建一个定时器 +1
+ (void)cancel:(NSString *)timerID{
if (!timerID || timerID.length <= 0) {
return;
}
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_source_t timer = timers[timerID];
if (timer) {
dispatch_source_cancel(timer);
[timers removeObjectForKey:timerID];
}
dispatch_semaphore_signal(sem);
}
@end
到此定时器就完成了,下面是如何使用
//开启定时器
[SXGCDTimer timerWithStartTime:0 interval:2 repeats:YES mainQueue:NO completion:^{
NSLog(@"第一种");
}];
//取消定时器
[SXGCDTimer cancel:@"1"];
到此定时器就完成了