GCD倒计时器速成

简单介绍

1、单例类管理GCD计时器;
2、类方法调用计时器API,方便快捷;
3、提供三组API,快速实现计时、倒计时、取消计时;
4、目前仅提供同时存在1组计时器;
5、计时结束后,自动取消,也可手动取消计时器;

注意事项

1、在页面加载和退出时,注意定时器的销毁。
2、及时调用销毁方法,避免释放不掉的问题。
例如:

+ (void)cancelSingleTimer;

.h

构建回调block

/*
每秒频单频计时器回调
current 每秒回调一次 回调当前的时间
end 当为TRUE时 定时器结束
*/

typedef void (^DKTimerSingleTimerBlock)(NSInteger current, BOOL end);

/*
DKTimer
*/

@interface DKTimer : NSObject

/*
倒计时
time:从xx秒开始倒计时
block: 回调
*/

+ (void)countdown:(NSInteger)time block:(DKTimerSingleTimerBlock)block;

/*
计时
max:计时xx时间
block: 回调
*/

+ (void)singleTimer:(NSInteger)max block:(DKTimerSingleTimerBlock)block;

/*
取消计时
*/

+ (void)cancelSingleTimer;

.m

声明属性

/*
每秒频单频计时器;
每次调用前,会销毁之前的定时器;
支持计时和倒计时。倒计时到0时,停止计时;
回调的block均为主线程;
*/

@property (strong, nonatomic) dispatch_source_t singleTimer;
@property (assign, nonatomic) NSInteger current;
@property (assign, nonatomic) NSInteger max;
@property (assign, nonatomic) BOOL sequence;
@property (copy, nonatomic) DKTimerSingleTimerBlock singleTimerBlock;

构建单例类

/*
单例类的创建
使用单例类创建定时器,在一定的环境下,可以高效的控制定时器。
*/

+ (DKTimer *)timer {
    static dispatch_once_t onceToken;
    static DKTimer *timer = nil;
    dispatch_once(&onceToken, ^{
        timer = [[DKTimer alloc] init];
    });
    return timer;
}

公有API

/*
倒计时 最小从1开始倒计时
time:从xx秒开始倒计时
block: 回调
*/

+ (void)countdown:(NSInteger)time block:(DKTimerSingleTimerBlock)block {
    if (time <= 0) {
        return;
    }
    [DKTimer timer].singleTimerBlock = block;
    [DKTimer timer].sequence = NO;
    [DKTimer timer].current = time;
    [[DKTimer timer] startSingleTime];
}

/*
计时
max:计时xx时间
block: 回调
*/

+ (void)singleTimer:(NSInteger)max block:(DKTimerSingleTimerBlock)block {
    [DKTimer timer].singleTimerBlock = block;
    [DKTimer timer].sequence = YES;
    [DKTimer timer].max = max;
    [DKTimer timer].current = 0;
    [[DKTimer timer] startSingleTime];
}

/*
取消计时
*/

+ (void)cancelSingleTimer {
    [[DKTimer timer] stopSingleTimer];
}

私有API

/*
计时器的回调方法 主线程
*/

- (void)singleTimerMethod {
    if ([DKTimer timer].sequence) {
        // 计时
        [DKTimer timer].current = [DKTimer timer].current + 1;
        BOOL end;
        if ([DKTimer timer].current > [DKTimer timer].max) {
            // 结束
            end = YES;
            [self stopSingleTimer];
        }else {
            // 继续
            end = NO;
        }
        if ([DKTimer timer].singleTimerBlock) {
            [DKTimer timer].singleTimerBlock([DKTimer timer].current, end);
        }
    }else {
        // 倒计时
        [DKTimer timer].current = [DKTimer timer].current - 1;
        BOOL end;
        if ([DKTimer timer].current < 0) {
            // 结束
            end = YES;
            [self stopSingleTimer];
        }else {
            // 继续
            end = NO;
        }
        if ([DKTimer timer].singleTimerBlock) {
            [DKTimer timer].singleTimerBlock([DKTimer timer].current, end);
        }
    }
}

计时器创建 开始 销毁

- (void)stopSingleTimer {
    if (_singleTimer) {
        dispatch_cancel(_singleTimer);
        _singleTimer = nil;
    }
}
- (void)startSingleTime {
    [self stopSingleTimer];
    __weak DKTimer *weakself = self;
    NSInteger timeSpace = 1;
    dispatch_queue_t queue = dispatch_get_main_queue();
    self.singleTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
    uint64_t interval = (uint64_t)(timeSpace * NSEC_PER_SEC);
    dispatch_source_set_timer(self.singleTimer, start, interval, 0);
    dispatch_source_set_event_handler(self.singleTimer, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakself singleTimerMethod];
        });
    });
    dispatch_resume(self.singleTimer);
}

IMG_2847.jpg

你可能感兴趣的:(GCD倒计时器速成)