zoukankan      html  css  js  c++  java
  • iOS定时器的使用

    iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD。

    NSTimer

    方式1

        // 创建定时器

        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES];


        // 停止定时器

        [timer invalidate];


    方式2

        // 创建定时器

        NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES];

        // 将定时器添加到runloop中,否则定时器不会启动

        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];


        // 停止定时器

        [timer invalidate];

    方式1会自动将创建的定时器以默认方式添加到当前线程runloop中,而无需手动添加。但是在此种模式下,当滚动屏幕时runloop会进入另外一种模式,定时器会暂停,为了解决这种问题,可以像方式2那样把定时器添加到NSRunLoopCommonModes模式下。

    方式1和方式2在设置后都会在间隔设定的时间(本例中设置为2s)后执行test方法,如果需要立即执行可以使用下面的代码。

    [time fire];

    CADisplayLink

        // 创建displayLink

        CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(test:)];

        // 将创建的displaylink添加到runloop中,否则定时器不会执行

        [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];


        // 停止定时器

        [displayLink invalidate];

        displayLink = nil;

    当把CADisplayLink对象add到runloop中后,selector就能被周期性调用,类似于重复的NSTimer被启动了;执行invalidate操作时,CADisplayLink对象就会从runloop中移除,selector调用也随即停止,类似于NSTimer的invalidate方法

    调用时机

    CADisplayLink是一个和屏幕刷新率同步的定时器类。CADisplayLink以特定模式注册到runloop后,每当屏幕显示内容刷新结束的时候,runloop就会向CADisplayLink指定的target发送一次指定的selector消息,CADisplayLink类对应的selector就会被调用一次,所以可以使用CADisplayLink做一些和屏幕操作相关的操作。

    重要属性

    • frameInterval
      NSInteger类型的值,用来设置间隔多少帧调用一次selector方法,默认值是1,即每帧都调用一次。
    • duration
      readOnly的CFTimeInterval值,表示两次屏幕刷新之间的时间间隔。需要注意的是,该属性在target的selector被首次调用以后才会被赋值。selector的调用间隔时间计算方式是:调用间隔时间 = duration × frameInterval。

    GCD定时器

    一次性定时

     dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);


     dispatch_after(timer, dispatch_get_main_queue(), ^(void){


            NSLog(@"GCD-----%@",[NSThread currentThread]);


        });


    重复执行的定时器

    @property (nonatomic ,strong)dispatch_source_t timer;//  注意:此处应该使用强引用 strong

    {

        //0.创建队列

        dispatch_queue_t queue = dispatch_get_main_queue();

        //1.创建GCD中的定时器

        /*

         第一个参数:创建source的类型 DISPATCH_SOURCE_TYPE_TIMER:定时器

         第二个参数:0

         第三个参数:0

         第四个参数:队列

         */

        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);


        //2.设置时间等

        /*

         第一个参数:定时器对象

         第二个参数:DISPATCH_TIME_NOW 表示从现在开始计时

         第三个参数:间隔时间 GCD里面的时间最小单位为 纳秒

         第四个参数:精准度(表示允许的误差,0表示绝对精准)

         */

        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);


        //3.要调用的任务

        dispatch_source_set_event_handler(timer, ^{

            NSLog(@"GCD-----%@",[NSThread currentThread]);

        });


        //4.开始执行

        dispatch_resume(timer);


        //

        self.timer = timer;

    }

    此处注意一定要强引用定时器 ,否则定时器执行到 } 后将会被释放,无定时效果。

  • 相关阅读:
    HDU 1009 FatMouse' Trade
    HDU 2602 (简单的01背包) Bone Collector
    LA 3902 Network
    HDU 4513 吉哥系列故事——完美队形II
    LA 4794 Sharing Chocolate
    POJ (Manacher) Palindrome
    HDU 3294 (Manacher) Girls' research
    HDU 3068 (Manacher) 最长回文
    Tyvj 1085 派对
    Tyvj 1030 乳草的入侵
  • 原文地址:https://www.cnblogs.com/pioneerMax/p/6089824.html
Copyright © 2011-2022 走看看