iOS GCD定时器

作者: 我就叫Tom怎么了 | 来源:发表于2017-08-15 15:38 被阅读0次

    GCD定时器的优势是不受RunLoop的运行模式的影响,它的的间隔时间是纳秒为单位。

    GCDTimer.h

    #import <Foundation/Foundation.h>
    
    typedef void (^TimerRunBlock)(NSUInteger currentTime);  //定时器计时回调
    typedef void (^TimerStopBlock)();                       //定时器结束计时回调
    
    @interface DPGCDTimer : NSObject
    
    @property (nonatomic,assign)BOOL isTimerRuning;         //定时器是否正在运行
    @property (nonatomic, copy) TimerStopBlock timerStopBlock;
    
    /**
     *  定时器初始化(定时器默认开启)
     *
     *  @param timeDuration  时长
     *  @param timerRunBlock 定时器回调
     */
    - (void)timerWithTimeDuration:(double)timeDuration withRunBlock:(TimerRunBlock)timerRunBlock;
    
    
    /**
     *  定时器停止
     */
    - (void)stopTimer;
    
    /**
     *  定时器恢复
     */
    - (void)resumeTimer;
    
    /**
     *  定时器暂停
     */
    - (void)suspendTimer;
    
    @end
    
    #import "DPGCDTimer.h"
    #define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self;
    
    @interface DPGCDTimer ()
    {
        dispatch_source_t __block timer;
    }
    
    @property (nonatomic,copy)TimerRunBlock timerRunBlock;
    
    @end
    
    @implementation DPGCDTimer
    
    - (void)timerWithTimeDuration:(double)timeDuration withRunBlock:(TimerRunBlock)timerRunBlock
    {
        if (!timer) {
            WS(weakSelf);
            //创建定时器
            _isTimerRuning = YES;
            NSUInteger __block time = timeDuration;
            
            self.timerRunBlock = timerRunBlock;
            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 * NSEC_PER_SEC, 0); //每秒执行
            dispatch_source_set_event_handler(timer, ^{
                if (time <= 0) {
                    [self stopTimer];
                } else {
                    if (weakSelf.timerRunBlock) {
                        weakSelf.timerRunBlock(time --);
                    }
                }
            });
            dispatch_resume(timer);
        }
        
    }
    
    //停止
    - (void)stopTimer
    {
        if(timer){
            if (_isTimerRuning) {
                dispatch_source_cancel(timer);
                timer = nil;
                _isTimerRuning = NO;
                if (self.timerStopBlock) {
                    self.timerStopBlock();
                }
            }
            
        }
    }
    
    //恢复
    - (void)resumeTimer
    {
        if(timer){
            if (!_isTimerRuning) {
                dispatch_resume(timer);
                _isTimerRuning = YES;
            }
            
        }
    }
    
    //暂停
    - (void)suspendTimer
    {
        if(timer){
            if (_isTimerRuning) {
                dispatch_suspend(timer);
                _isTimerRuning = NO;
            }
        }
    }
    
    
    @end
    

    PS:
    GCD 中刷新UI导致线程崩溃问题工具 - PSPDFUIKitMainThreadGuard
    工具使用方法就是把这个.m文件拖入工程,如果有问题就会PSPDFAssert断点处停住。在左侧线程分析中点击查看出现错误的地方。

    相关文章

      网友评论

        本文标题:iOS GCD定时器

        本文链接:https://www.haomeiwen.com/subject/mjcvrxtx.html