引言:上期写了Swift的Timer倒计时和正向计时方法,这期来记录一下OC中的Timer倒计时和正向计时方法
特点:此次用到了单例模式来减少后台资源的消耗。 (单例模式是指一个类只返回一个对象,无论创建多少次,都只返回一个对象。单例模式可以有效解决一个全局使用的类被频繁创建和销毁带来的系统性能下降,以及资源的多重占用。)
创建Timer类
// Timer.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^TimingBlock)(int recordTime);
typedef void(^TimeCompleteBlock)(void);
@interface Timer : NSObject
+ (instancetype)shareInstance;
///倒计时
/// - Parameters:
/// - maxtime: 倒计时时长
/// - timingblock:计时间隔回调
/// - complete: 倒计时完成时回调
- (void)startTimingWithMaxtime:(int)maxtime
timingBlock:(TimingBlock)timingblock
complete:(TimeCompleteBlock)complete;
/// 正向计时
/// - Parameters:
/// - startTime: 起始时间 格式为:yyyy-MM-dd HH:mm:ss
/// - timingBlock: 计时间隔回调
- (void)startPositiveTimingWithStartTime:(NSString *)startTime timingBlock:(TimingBlock)timingBlock;
/// 取消计时
- (void)cancelTiming;
@end
NS_ASSUME_NONNULL_END
// Timer.m
#import "Timer.h"
@interface Timer () {
dispatch_source_t timer;
}
@end
@implementation Timer
+ (instancetype)shareInstance {
static Timer * instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[Timer alloc] init];
});
return instance;
}
- (void)startTimingWithMaxtime:(int)maxtime
timingBlock:(TimingBlock)timingblock
complete:(TimeCompleteBlock)complete {
// 计时
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); // 每秒执行
NSDate *endTime = [NSDate dateWithTimeIntervalSinceNow:maxtime]; // 结束时间
dispatch_source_set_event_handler(timer, ^{
__block int intinterval = [endTime timeIntervalSinceNow];
if (intinterval >= 0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (timingblock) {
timingblock(intinterval);
NSLog(@"计时为:%ld", (long)(NSInteger)intinterval);
}
});
} else {
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
//根据自己需求设置
NSLog(@"计时结束");
if (complete) {
complete();
}
});
}
});
dispatch_resume(timer);
}
- (void)startPositiveTimingWithStartTime:(NSString *)startTime timingBlock:(TimingBlock)timingBlock {
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), 1.0*NSEC_PER_SEC, 0); // 每秒执行
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *startDate = [format dateFromString:startTime];
if (!startDate) {
return;
}
dispatch_source_set_event_handler(timer, ^{
NSDate *endTime = [NSDate date];
NSTimeInterval timeInterval = [endTime timeIntervalSinceDate:startDate];
dispatch_async(dispatch_get_main_queue(), ^{
if (timingBlock) {
timingBlock(timeInterval);
NSLog(@"计时为:%ld,记得调用cancelTiming方法取消计时", (long)(NSInteger)timeInterval);
}
});
});
dispatch_resume(timer);
}
/** 取消计时 */
- (void)cancelTiming {
if (timer) {
dispatch_source_cancel(timer);
}
}
@end
使用方法:
/// 倒计时方法使用
[[Timer shareInstance] startTimingWithMaxtime:1800 timingBlock:^(int recordTime) {
/// 计时间隔回调
NSLog(@"倒计时剩余时间:%d", recordTime);
} complete:^{
/// 计时器终止
[[Timer shareInstance] cancelTiming];
/// 计时结束回调操作
}];
/// 正向计时方法使用(从当前时间进行正向计时)
[[Timer shareInstance] startPositiveTimingWithStartTime:[NSDate.now dateForString:@"yyyy-MM-dd HH:mm:ss"] timingBlock:^(int recordTime) {
/// ps:记得实现需求后进行终止计时器操作;
/// [[Timer shareInstance] cancelTiming];
}];
注:OC单例模式参考资料:【OC】单例模式
整理不易,望大家多多点赞收藏,希望对大家有所帮助!
如果有误,请各位大佬指点!谢谢大家!!!