「OC」Timer单例模式倒计时和正向计时

引言:上期写了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】单例模式

整理不易,望大家多多点赞收藏,希望对大家有所帮助!
如果有误,请各位大佬指点!谢谢大家!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡酒交魂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值