NSTimer 与 Runloop 关系分析

    [NSTimer scheduledTimerWithTimeInterval:4.0
                                     target:self
                                   selector:@selector(clickAction)
                                   userInfo:nil
                                    repeats:YES];

在项目里,这就是使用 NSTimer 最常用的方式 -- 在 vc 里定时或者延迟执行某个方法,可是又有多少个coder会想知道它和 Runloop 的关系?

当使用 NSTimer 的 scheduledTimerWithTimeInterval 方法时,事实上此时 NSTimer 会被加入到当前的 Runloop 中而且模式是默认的 NSDefaultRunLoopMode。而如果当前线程就是主线程(UI线程), 在某些UI事件中,比如 UIScrollView 的拖动,会将 Runloop 切换成 NSEventTrackingRunLoopMode 模式,在这个过程中,默认的NSDefaultRunLoopMode 模式中注册的事件是不会被执行的。也就是说,此时使用 scheduledTimerWithTimeInterval 添加到 Runloop 中的 NSTimer 就不会执行。

实际需求:如何设置一个不被UI干扰的NSTimer?

需要手动创建一个 Timer,然后使用 NSRunLoop 的 addTimer:forMode:方法来把 Timer 按照指定模式加入到 RunLoop 中。这里使用的模式是: NSRunLoopCommonModes,这个模式等效于 NSDefaultRunLoopModeNSEventTrackingRunLoopMode 的结合

示例 e.g

//创建Timer
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timer_callback) userInfo:nil repeats:YES];
//使用NSRunLoopCommonModes模式,把timer加入到当前Run Loop中。
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

NSTimer添加到Runloop中,但是不运行?

在iOS多线程中,每一个线程都有一个 Runloop,但是只有主线程的 Runloop 默认是打开的,其他子线程也就是我们创建的线程的 Runloop默认是关闭的,需要我们手动运行。我们可以通过 [NSRunLoop currentRunLoop] 来获得当前线程的 Runloop,并且调用
[runloop addTimer:timer forMode:NSDefaultRunLoopMode] 方法将定时器添加到 Runloop 中,最后一定不要忘记调用 Runloop 的 run 方法将当前 Runloop 开启,否则 NSTimer 永远也不会运行。

附录:苹果官方定义的Runloop的类型


QQ20151213-1@2x.png

网上看到比较好的文章记录:

  1. NSTimer和Runloop的关系 分析了平时使用NSTimer的注意点、实时性还有和 Runloop 的关系,特别是和 Runloop 的关系分析的挺细致的
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 基本概念 进程 进程是指在系统中正在运行的一个应用程序,而且每个进程之间是独立的,它们都运行在其专用且受保护的内存...
    小枫123阅读 4,423评论 0 1
  • 一、什么是runloop 字面意思是“消息循环、运行循环”。它不是线程,但它和线程息息相关。一般来讲,一个线程一次...
    WeiHing阅读 12,507评论 11 111
  • RunLoop 文章目录 RunLoop简介 1.1 什么是RunLoop? 1.2 RunLoop和线程 1.3...
    May_d8f1阅读 2,241评论 0 1
  • 文章目录RunLoop简介1.1 什么是RunLoop? 1.2 RunLoop和线程1.3 默认情况下主线程的R...
    lusen_b阅读 2,976评论 0 2
  • ======================= 前言 RunLoop 是 iOS 和 OSX 开发中非常基础的一个...
    i憬铭阅读 4,373评论 0 4