@property (nonatomic, strong) dispatch_source_t timer;
获取全局子线程队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
创建timer添加到队列中
_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(self->_timer);
dispatch_async(dispatch_get_main_queue(), ^{
回到主线程处理UI
});
} else { // 倒计时重新计算 时/分/秒
});
timeout--; // 递减 倒计时-1(总时间以秒来计算)
}
});
dispatch_resume(_timer);
这是常规的做法,但是某种情况下,如果GCDTimer在tableviewCell中,tableView reload可能会再一次的初始化GCDTimer,所以说在初始化之前需要取消之前的GCDTimer,再进行初始化,由此写了个单例把GCDTimer仍里边,代码如下
// WPGCDtimerManager.m
// WanPiao
//
// Created by 俊洋洋 on 2018/8/20.
// Copyright © 2018年 俊洋洋. All rights reserved.
//
#import "WPGCDtimerManager.h"
@interface WPGCDtimerManager()
@end
@implementation WPGCDtimerManager
// 单例
+ (WPGCDtimerManager *)sharedInstance
{
static WPGCDtimerManager *_wpGCDTimerManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_wpGCDTimerManager = [[WPGCDtimerManager alloc] init];
});
return _wpGCDTimerManager;
}
// 取消timer
- (void)cancelOrderTimerWithName:(NSString *)timerName
{
dispatch_source_t timer = [self.orderTimerGCDDict objectForKey:timerName];
if (!timer)
return;
[self.orderTimerGCDDict removeObjectForKey:timerName];
dispatch_source_cancel(timer);
}
- (NSMutableDictionary *)orderTimerGCDDict
{
if (!_orderTimerGCDDict) {
_orderTimerGCDDict = [[NSMutableDictionary alloc] init];
}
return _orderTimerGCDDict;
}
@end
在tableViewCell中可这样写
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
// [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:8]];//解决8小时时间差问题
NSDate *orderDate = [dateFormatter dateFromString:model.orderTime];
NSTimeInterval interval = 60*15;
NSDate *countDownDate = [NSDate dateWithTimeInterval:interval sinceDate:orderDate];
// 倒计时的时间 测试数据
NSString *deadlineStr = [dateFormatter stringFromDate:countDownDate];
// 当前时间的时间戳
NSString *nowStr = [LYTool getCurrentTimeyyyymmdd];
// 计算时间差值
NSInteger secondsCountDown = [LYTool getDateDifferenceWithNowDateStr:nowStr deadlineStr:deadlineStr];
WEAKSELF
__block NSInteger timeout = secondsCountDown; // 倒计时时间
if (timeout!=0) {
//取消之前创建的GCDTimer
[[WPGCDtimerManager sharedInstance] cancelTimerWithName:@"ConfirmOrderTimerGCD"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//记录刚创建的timer
[[WPGCDtimerManager sharedInstance].confirmTimerGCDDict setObject:_timer forKey:@"ConfirmOrderTimerGCD"];
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(self->_timer);
dispatch_async(dispatch_get_main_queue(), ^{
});
} else { // 倒计时重新计算 时/分/秒
dispatch_async(dispatch_get_main_queue(), ^{
});
timeout--; // 递减 倒计时-1(总时间以秒来计算)
}
});
dispatch_resume(_timer);
}