iosGCD定时器使⽤,封装为单例
1. 原因
当使⽤定时器时,如果viewcontroller被pop后,⾃动销毁内部的定时器,导致重新push到view之后,⼜要重新开始计时。
加⼯部分:
增加了两个block块作为属性,在实际使⽤中很有效。
2. 上代码
SingleTimer.h
import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^TimeoutCallBack)(NSString *text);
typedef void (^TimeinCallBack)(void);
@interface SingleTimer : NSObject
@property (nonatomic,assign) NSInteger    timeRange;            //计时时间
@property (nonatomic,assign) NSInteger    timeRest;              //计时时间
@property (nonatomic ,copy)  TimeinCallBack      TimeinCall;  //在计时时调⽤
@property (nonatomic ,copy)  TimeoutCallBack      TimeoutCall; //在计时结束时调⽤
@property (nonatomic,strong) dispatch_source_t  timer;        //计时器
+ (id)sharedTimerManager;
- (void) startTimer;
- (void) pauseTimer;
- (void) resumeTimer;
- (void) stopTimer;
@end
SingleTime.m
@interface SingleTimer()
@property (nonatomic,assign) NSInteger TimeRemain;
@end
@implementation SingleTimer
+ (id)sharedTimerManager{
static SingleTimer *manager =nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (manager ==nil) {
manager = [[self alloc]init];
}
});
return manager;
return manager;
}
//时间计算
- (void)startTimer{
if (self.timeRange <=0) {
return;
}
/
controller单例还是多例/ 倒计时的时间测试数据
NSInteger deadlineSecond = self.TimeRemain>0?:self.timeRange; //单位秒
// 当前时间的时间戳
NSString *nowStr = [self getCurrentTimeyyyymmdd];
NSLog(@"nowStr:%@",nowStr);
// 计算时间差值
CGFloat secondsCountDown = [self getDateDifferenceWithNowDateStr:nowStr deadlineSecond:deadlineSecond];    NSLog(@"secondsCountDown:%.0f",secondsCountDown);
__weak __typeof(self) weakSelf = self;
if (_timer == nil) {
__block NSInteger timeout = secondsCountDown; // 倒计时时间
if (timeout!=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), 1.0*NSEC_PER_SEC,  0); //每秒执⾏
dispatch_source_set_event_handler(_timer, ^{
if(timeout <= 0){ //  当倒计时结束时做需要的操作:
dispatch_source_cancel(weakSelf.timer);
weakSelf.timer = nil;
self.timeRest  = 0;
self.TimeRemain = 0;
dispatch_async(dispatch_get_main_queue(), ^{
if (_TimeinCall) {
_TimeinCall();
}
});
} else { // 倒计时重新计算时/分/秒
NSInteger days = (int)(timeout/(3600*24));
NSInteger hours = (int)((timeout-days*24*3600)/3600);
NSInteger minute = (int)(timeout-days*24*3600-hours*3600)/60;
NSInteger second = timeout - days*24*3600 - hours*3600 - minute*60;
NSString *strTime = [NSString stringWithFormat:@"剩余时间: %02ld分%02ld秒", minute, second];
dispatch_async(dispatch_get_main_queue(), ^{
if (_TimeoutCall) {
_TimeoutCall(strTime);
}
});
timeout--; // 递减倒计时-1(总时间以秒来计算)
self.timeRest = self.timeRange - timeout;
self.TimeRemain = timeout;
}
});
dispatch_resume(_timer);
}
}
}
-(void) pauseTimer{
if(self.timer){
dispatch_suspend(_timer);
}
}
}
-(void) resumeTimer{
if(self.timer){
dispatch_resume(_timer);
}
}
-(void) stopTimer{
if(self.timer){
dispatch_source_cancel(_timer);
self.timeRest  = 0;
self.TimeRemain = 0;
_timer = nil;
}
}
/**
*  获取当天的字符串
*  @return 格式为年-⽉-⽇时分秒
*/
- (NSString *)getCurrentTimeyyyymmdd {
NSDate *now = [NSDate date];
NSDateFormatter *formatDay = [[NSDateFormatter alloc] init];
formatDay.dateFormat = @"mm:ss";
NSString *dayStr = [formatDay stringFromDate:now];
return dayStr;
}
/**
*  获取时间差值截⽌时间-当前时间
*  nowDateStr : 当前时间
*  deadlineSecond : 计时器秒数
*  @return 时间戳差值
*/
- (NSInteger)getDateDifferenceWithNowDateStr:(NSString*)nowDateStr deadlineSecond:(CGFloat)deadlineSecond {    NSInteger timeDifference = 0;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"mm:ss"];
NSDate *nowDate = [formatter dateFromString:nowDateStr];
NSTimeInterval oldTime = [nowDate timeIntervalSince1970];
NSTimeInterval newTime = [nowDate timeIntervalSince1970] + deadlineSecond;
timeDifference = newTime - oldTime;
return timeDifference;
}
@end