美文网首页
定时器 与 NSRunLoop

定时器 与 NSRunLoop

作者: coder_hong | 来源:发表于2017-04-09 14:30 被阅读192次

GCD定时器


Snip20170409_3.png

注意点:下面代码中的timer是一个局部的变量,走出代码块,被销毁;所以定时器中的方法不会执行

/*
     * @param dispatchQueue
     * @param intervalInSeconds 间隔时间秒
     * @param leewayInSeconds 允许的误差 如果传0 为没有误差
     *
     */
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"++++++++++++++++++++%@", [NSThread currentThread]);
    });
    dispatch_resume(timer);

对上面的解决办法:内部有一个强引用 引用着timer

@interface TestViewController ()
{
    dispatch_source_t _mytimer;
}

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    _mytimer = timer;
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"++++++++++++++++++++%@", [NSThread currentThread]);
    });
// 开启定时器
    dispatch_resume(timer);

当我们需要停止定时器的时候,执行该方法:
注意:当在停止后不能再调用dispatch_resume方法打开定时器,否则导致程序奔溃。

dispatch_source_cancel(_mytimer);

NSTimer


NSTimer定时器使用:
这里timer同样是一个局部变量,但是在函数体走完只有timer并没有销毁,所以定时器是可以正常工作,内部应该已经对timer有了一个强引用

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(test) userInfo:nil repeats:YES];
    // 执行定时器
    [timer fire];

// 定时器方法
- (void)test
{
    NSLog(@"-------------");
}

同样的,当需要停止定时器的时候,调用该方法

- (void)invalidate;

如果需要再次开启定时器的时候,不可以在对该timer执行fire方法开启,而是需要充新创建一个新的定时器进行赋值

- (IBAction)switchAction:(UISwitch *)sender {
    
    if (sender.isOn) { // 打开
        
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(test) userInfo:nil repeats:YES];
    [self.timer fire];
        
    }else{ // 关闭
        [self.timer invalidate];
    }
}

NSTimer定时器受NSRunloop影响:当timer被创建了以后,timer被添加到当前RunLoop的NSDefaultRunLoopMode模式。而如果当前线程就是主线程,也就是UI线程时,某些UI事件,比如UIScrollView的拖动操作,会将Run Loop切换成NSEventTrackingRunLoopMode模式,在这个过程中,默认的NSDefaultRunLoopMode模式中注册的事件是不会被执行的

为了设置一个不被UI干扰的Timer,我们需要手动创建一个Timer,然后使用NSRunLoop的addTimer:forMode:方法来把Timer按照指定模式加入到Run Loop中。这里使用的模式是:NSRunLoopCommonModes,这个模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的结合

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(test) userInfo:nil repeats:YES];
    // 执行定时器
    [timer fire];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:UITrackingRunLoopMode];

NSRunLoop


NSRunLoop的特点

  • 每条线程都有唯一的一个与之对应的RunLoop对象
  • 主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建
  • RunLoop在第一次获取时创建,在线程结束时销毁

NSRunLoop的模式

如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入

RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source(Sources0、Sources1)、Timer,那么就直接退出RunLoop

系统默认注册了5个Mode:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行

UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用

GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到

kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode

相关文章

  • 浅析 NSTimer & CADisplayLink 内

    偶得前言 NSRunLoop与定时器 [- invalidate的作用](#- invalidate的作用) 我们...

  • 定时器 与 NSRunLoop

    GCD定时器 注意点:下面代码中的timer是一个局部的变量,走出代码块,被销毁;所以定时器中的方法不会执行 对上...

  • IOS开发笔记

    1.使用定时器时,避免移动界面时,导致定时器暂停: [[NSRunLoop currentRunLoop] add...

  • iOS常见知识点

    1.滑动UIScrollView时不影响定时器NSTimer [[NSRunLoop mainRunLoop] a...

  • NSTimer

    创建一个 Timer 启动 Timer – fire//加定时器 [[NSRunLoop currentRunLo...

  • SDWebImage&&NSRunloop笔记

    SDWebImage: NSCache: NSRunloop: GCD定时器: 线程的任务执行完之后就会进入死亡状...

  • iOS 定时器延迟执行

    1、NSRunLoop 2、定时器 3、GCD https://www.jianshu.com/p/2d57c72...

  • iOS ->几秒后 执行某个方法

    在开发过程中经常会用到:几秒后 执行某个方法 1、NSRunLoop 2、定时器 3、GCD

  • runloop关系篇

    NSRunloop关系篇 1.NSRunloop 与 NSTimer .https://blog.csdn.net...

  • 10.NSTimer的使用笔记

    1.前言 2.定时器NSTimer的一个被添加进NSRunLoop的使用细节: 在NSTimer schedule...

网友评论

      本文标题:定时器 与 NSRunLoop

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