美文网首页
实现倒计时的三种方式

实现倒计时的三种方式

作者: 为什么划船不靠桨 | 来源:发表于2018-06-07 13:59 被阅读0次

在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法。在这个时候,我们就需要用到定时器。在iOS中有很多方法完成定时器的任务,例如 NSTimer、CADisplayLink 和 GCD都可以。

一、NSTimer

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
//销毁定时器
//[timer invalidate];
其特点是使用上面的创建方式,会自动把timer加入当前线程的运行循环中
NSTimer *timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
其特点是如果使用以上面的方式创建定时器,就必须手动加入Runloop运行循环中,否则方法无法正常执行.
当我们是在子线程中创建定时器时,因为子线程的NSRunLoop默认是不开启的,所以我们还需要开启子线程的NSRunLoop

方式一

//创建子线程
    [NSThread detachNewThreadWithBlock:^{
        
        //在子线程中创建定时器
        NSTimer *t = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
            NSLog(@"👌%@",[NSThread currentThread]);
        }];
        //在当前子线程的RunLoop中添加定时器
        [[NSRunLoop currentRunLoop] addTimer:t forMode:NSRunLoopCommonModes];
        //开启当前子线程的运行循环
        NSRunLoop *r = [NSRunLoop currentRunLoop];
        [r run];
    }];

方式二

//创建子线程
        [NSThread detachNewThreadWithBlock:^{
            
            //在子线程中创建定时器
            [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
                NSLog(@"👌%@",[NSThread currentThread]);
                
            }];
            //开启子线程的运行循环
            NSRunLoop *r = [NSRunLoop currentRunLoop];
            [r run];
        }];

二、GCD

//设置倒计时时间
    //通过检验发现,方法调用后,timeout会先自动-1,所以如果从15秒开始倒计时timeout应该写16
    __block NSInteger timeout = 10;
    //获取全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //创建一个定时器,并将定时器的任务交给全局队列执行(并行,不会造成主线程阻塞)
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
    // 设置触发的间隔时间(设置定时器触发的时间间隔为1s)
    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(timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //返回主线程刷新UI
            });
        }else{
            dispatch_async(dispatch_get_main_queue(), ^{
                //返回主线程刷新UI
                NSLog(@"%ld",timeout);
            });
        }
        timeout--;
    });
    dispatch_resume(timer);
//这里需要添加一个强引用,否则方法执行完timer对象就被释放了
self.timer = timer;

三、CADisplayLink

CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(logaction)];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    displayLink.preferredFramesPerSecond = 1.0f;
    //销毁定时器
//    [displayLink invalidate];
//    displayLink = nil;
注意点是CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。
NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

相关文章

  • ios 倒计时

    1、倒计时一般的三种方法 NSTimer Thread方式实现 GCD 2、cell中多个倒计时的情况 用NSTi...

  • iOS-倒计时实现的三种方式

    倒计时实现由三种方式,一种是NSTimer,第二种是是CADisplayLink,第三中是通过GCD的方式来实现,...

  • iOS实现倒计时的三种方式

    iOS实现倒计时的三种方式 做iOS app开发的过程当中,经常会出现获取验证码等需求,这个时候一般会使用倒计时来...

  • Java实现线程的三种方式和区别

    Java实现线程的三种方式和区别 Java实现线程的三种方式: 继承Thread 实现Runnable接口 实现C...

  • 实现倒计时的三种方式

    在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法。在这个时候,我们就需要...

  • 倒计时

    ios怎么在cell上添加倒计时 iOS中 简单易懂的秒杀倒计时/倒计时 iOS开发-三种倒计时的写法 iOS实现...

  • 没有介绍直接上代码,自己用

    实现现成三种方式:Thread(继承)、Runnable(实现)、CallAble(实现)

  • view实现3D旋转效果

    实现动画效果三种方式:

  • 01-spark实践—wordcount

    wordcount实现的三种方式 第一种方式: 第二种方式: 第三种方式:

  • 线程的创建-三种方式

    三种创建方式 一:继承Thread方式 二:实现Runnable接口 三:实现Callable接口实现 调用示例 ...

网友评论

      本文标题:实现倒计时的三种方式

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