ios GCD定时器使用,封装为单例

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;
    
}

//时间计算
- (void)startTimer{
    
    if (self.timeRange <=0) {
        return;
    }
    // 倒计时的时间 测试数据
    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
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

路途遥远gg

帮到你了就好

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

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

打赏作者

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

抵扣说明:

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

余额充值