美文网首页
iOS-GCD定时器的使用

iOS-GCD定时器的使用

作者: 我是何先生 | 来源:发表于2018-09-15 14:58 被阅读1101次

    在iOS开发的过程中定时器的使用比较频繁的,比较常见的场景是验证码的发送,或者是倒计时的展示.一般的需求我们直接使用NSTimer就能完成。但是NSTimer的坑也是比较多的,比如在UITableview的时候,需要把NSTimer添加到主循环,并且设置为NSRunLoopCommonModes。但是今天要记录的是:GCD定时器

    先直接贴代码

    File:GCDCountDown.h
    
    @interface GCDCountDown()
    @property(nonatomic,strong)dispatch_source_t timer;
    +(instancetype)manager;
    -(void)resume;
    -(void)pause;
    @end
    *************************************************************************************
    
    File:GCDCountDown.m
    
    @implementation GCDCountDown
    +(instancetype)manager{
        static GCDCountDown *countDown = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (countDown == nil) {
                countDown = [[GCDCountDown alloc]init];
            }
        });
        
        return countDown;
    }
    
    -(instancetype)init{
        self = [super init];
        if (self) {
            [self loadTimer];
        }
        return self;
    }
    
    //定时器设置
    -(void)loadTimer{
        if (self.timer) {
            dispatch_cancel(self.timer);
            self.timer = nil;
        }
        
        
        dispatch_queue_t queue = dispatch_get_main_queue();
        //创建一个定时器(dispatch_source_t本质上还是一个OC对象)
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        
        //设置定时器的各种属性
        dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0*NSEC_PER_SEC));
        uint64_t interval = (uint64_t)(1.0*NSEC_PER_SEC);
        dispatch_source_set_timer(self.timer, start, interval, 0);
        
        
        //设置回调
        __weak typeof(self) weakSelf = self;
        dispatch_source_set_event_handler(self.timer, ^{
            //定时器需要执行的操作
            [weakSelf timerAction];
           
        });
        //启动定时器(默认是暂停)
        dispatch_resume(self.timer);
        
    }
    
    -(void)resume{
        //重新加载一次定时器
        [self loadTimer];
        
    }
    -(void)pause{
        if (self.timer) {
            dispatch_cancel(self.timer);
            self.timer = nil;
        }
        
    }
    
    @end
    

    这是为了适配项目的需求封装的一个简单的定时器单例,精简了一些业务代理,不过主要的用法都贴出来了。GCD定时器的定义和使用就是这么简单,但是其中有几点是需要说明的:

    • dispatch_source_t 在本质上是一个对象,所以我们使用强引用。我们可以点击dispatch_source_t跳转到source.h文件看到,改对象使用宏定义,进行了一系列操作定义对象。
      dispatch_source_t展开后的定义是:

    @protocol OS_dispatch_source <OS_dispatch_object>
    @end
    typedef NSObject<OS_dispatch_source>* dispatch_source_t

    也就是dispatch_source_t 就是一个NSObjective对象。对于想深入了解的同学自行百度(主要是本人实在没有那么多精力看源码)

    • 定时器的暂停使用的是:dispatch_cancel(self.timer) 很明显这个我们可以清楚得看到也是一个宏定义,至于他的内部操作,请参考上一句话
    • 相对于NSTimer来说GCD定时器更加精确,并且不用考虑运行模式,因为NSTimer其实是延迟把事件放到RunLoop中执行,如果遇到其他的事件导致NSTimer的事件执行错过了运行周期,就会导致NSTimer的事件要到下一个周期才能运行。

    相关文章

      网友评论

          本文标题:iOS-GCD定时器的使用

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