美文网首页iOS程序员
iOS开发- 运行循环RunLoop定时器(三)

iOS开发- 运行循环RunLoop定时器(三)

作者: 037e3257fa3b | 来源:发表于2017-01-19 23:08 被阅读64次

    在主线程中开启定时器

    1.方法一:

    //该方法内部自动添加到runloop中,并且设置运行模式为默认(上一篇讲到运行模式有五种)
        [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    

    2.方法二

    //1.创建定时器
       NSTimer *timer =  [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
        
        //2.添加定时器到runLoop中,指定runloop的运行模式为NSDefaultRunLoopMode
        /*
         第一个参数:定时器
         第二个参数:runloop的运行模式
         */
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    

    3.问题:通过上面两个方法我们都能开启一个定时器,但是在某些情况下存在一定的问题。在一个控制器里面放一个tableview,同时用上述开启一个定时器,你会发现在滚动tableview时,定时器不执行相应的方法。为什么?这是因为运行循环同时只能存在一种运行模式,当我们在滑动tableview时,运行循环的运行模式是UITrackingRunLoopMode,而我们在定时器添加到了默认的模式下,所以在滑动tableview时定时器就失灵了。
    解决方法:有一个运行模式是kCFRunLoopCommonModes,这是一个占用、标签模式,怎么理解了,你可以认为就是NSRunLoopCommonModes = NSDefaultRunLoopMode + UITrackingRunLoopMode。其实是在NSDefaultRunLoopMode 和 UITrackingRunLoopMode模式上都打上了kCFRunLoopCommonModes的标签。当你把定时器添加到kCFRunLoopCommonModes模式后,不管当前运行模式处于NSDefaultRunLoopMode 模式 还是 处于UITrackingRunLoopMode模式,都会执行。

    3.GCD中的定时器
    直接贴上某老师的代码,讲得很好

    #import "ViewController.h"
    
    @interface ViewController ()
    /** 注释 */
    @property (nonatomic, strong) dispatch_source_t timer;
    @end
    
    @implementation ViewController
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"%s",__func__);
        
        
        //1.创建GCD中的定时器
        /*
         第一个参数:source的类型DISPATCH_SOURCE_TYPE_TIMER 表示是定时器
         第二个参数:描述信息,线程ID
         第三个参数:更详细的描述信息
         第四个参数:队列,决定GCD定时器中的任务在哪个线程中执行
         */
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
        
        //2.设置定时器(起始时间|间隔时间|精准度)
        /*
         第一个参数:定时器对象
         第二个参数:起始时间,DISPATCH_TIME_NOW 从现在开始计时
         第三个参数:间隔时间 2.0 GCD中时间单位为纳秒
         第四个参数:精准度 绝对精准0
         */
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.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;
    }
    @end
    

    相关文章

      网友评论

      • d2587c509cae:我想问下,我想做一个到准点就触发事件的定时器该怎么做?

      本文标题:iOS开发- 运行循环RunLoop定时器(三)

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