You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

214 lines
5.0 KiB

//
// WXYZ_GCDTimer.m
// WXReader
//
// Created by Andrew on 2020/6/18.
// Copyright © 2020 Andrew. All rights reserved.
//
#import "WXYZ_GCDTimer.h"
@interface WXYZ_GCDTimer ()
{
dispatch_source_t __block timer;
WXYZ_GCDTimerState _timerState;
double _timeDuration;
double _interval;
BOOL _immediatelyCallBack;
}
@end
@implementation WXYZ_GCDTimer
// 循环定时器(每秒循环一次)
- (instancetype)initCycleTimerWithImmediatelyCallBack:(BOOL)immediatelyCallBack
{
if (self = [super init]) {
_timerState = WXYZ_GCDTimerStateStoped;
_immediatelyCallBack = immediatelyCallBack;
_timeDuration = 0;
_interval = 1;
}
return self;
}
// 循环计时器
- (instancetype)initCycleTimerWithInterval:(double)interval immediatelyCallBack:(BOOL)immediatelyCallBack
{
if (self = [super init]) {
_timerState = WXYZ_GCDTimerStateStoped;
_immediatelyCallBack = immediatelyCallBack;
_timeDuration = 0;
_interval = interval;
}
return self;
}
// 倒计时计时器(每秒循环一次)
- (instancetype)initCountdownTimerWithTimeDuration:(double)timeDuration immediatelyCallBack:(BOOL)immediatelyCallBack
{
if (self = [super init]) {
_timerState = WXYZ_GCDTimerStateStoped;
_immediatelyCallBack = immediatelyCallBack;
_timeDuration = timeDuration;
_interval = 1;
}
return self;
}
// 设定时间间隔倒计时计时器
- (instancetype)initCountdownTimerWithTimeDuration:(double)timeDuration interval:(double)interval immediatelyCallBack:(BOOL)immediatelyCallBack
{
if (self = [super init]) {
_timerState = WXYZ_GCDTimerStateStoped;
_immediatelyCallBack = immediatelyCallBack;
_timeDuration = timeDuration;
_interval = interval;
}
return self;
}
/**
* 定时器开启
*/
- (void)startTimer
{
if (timer && _timerState == WXYZ_GCDTimerStatePausing) {
[self resumeTimer];
}
[self stopTimer];
[self createzhishudaliTimer];
}
- (void)startTimerWithTimeDuration:(double)timeDuration
{
_timeDuration = timeDuration;
[self startTimer];
}
/**
* 定时器停止
*/
- (void)stopTimer
{
if(timer) {
if (_timerState == WXYZ_GCDTimerStateRunning) {
dispatch_source_cancel(timer);
timer = nil;
_timerState = WXYZ_GCDTimerStateStoped;
if (self.timerTerminateBlock) {
self.timerTerminateBlock();
}
}
}
}
/**
* 定时器恢复
*/
- (void)resumeTimer
{
if(timer) {
if (_timerState == WXYZ_GCDTimerStatePausing) {
dispatch_resume(timer);
_timerState = WXYZ_GCDTimerStateRunning;
if (self.timerResumeBlock) {
self.timerResumeBlock();
}
}
}
}
/**
* 定时器暂停
*/
- (void)suspendTimer
{
if(timer){
if (_timerState == WXYZ_GCDTimerStateRunning) {
dispatch_suspend(timer);
_timerState = WXYZ_GCDTimerStatePausing;
if (self.timerSuspendBlock) {
self.timerSuspendBlock();
}
}
}
}
#pragma privite
/**
* 定时器任务完成
*/
- (void)finishTimer
{
if(timer) {
if (_timerState == WXYZ_GCDTimerStateRunning) {
dispatch_source_cancel(timer);
timer = nil;
_timerState = WXYZ_GCDTimerStateStoped;
if (self.timerFinishedBlock) {
self.timerFinishedBlock();
}
}
}
}
- (void)createzhishudaliTimer
{
WS(weakSelf)
BOOL __block kImmediatelyCallBack = _immediatelyCallBack;
double __block kTimeDuration = _timeDuration <= 0 ? HUGE_VAL : _timeDuration;
// 计时器时间不正确
if (kTimeDuration <= 0) {
if (self.timerFinishedBlock) {
self.timerFinishedBlock();
}
return;
}
if (_interval == 0) {
_interval = 1;
}
NSUInteger __block runTimes = 0;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer,dispatch_walltime(NULL, 0), _interval * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
runTimes ++;
_timerState = WXYZ_GCDTimerStateRunning;
if (kTimeDuration <= 0) {
[weakSelf finishTimer];
} else {
kTimeDuration = kTimeDuration - _interval;
if (kImmediatelyCallBack) {
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf.timerRunningBlock) {
weakSelf.timerRunningBlock(runTimes, kTimeDuration != INFINITY ?kTimeDuration:0.f);
}
});
}
kImmediatelyCallBack = YES;
}
});
dispatch_resume(timer);
if (self.timerStartBlock) {
self.timerStartBlock();
}
}
@end