iOS NSTimer引发的RunLoop

作为iOS开发者应该会接触到定时器NSTimer,那么下面的代码就不会陌生

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

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

上面代码的大概意思就是创建一个NSTimer并把NSTimer放到RunLoop中,然后就会每1秒钟执行一次run方法。

首先,抽象的了解一下RunLoop,RunLoop大致可以想象成一个死循环,像下面这样

 do{
       
       //do something
           
   } while(1);

然而实际会比这种简单的循环复杂的多,RunLoop通过do-while来让程序持续运行,接受用户输入,调度事件,同时当每户没有输入、没有调度事件的时候就让CPU休息,节省CPU。

1 .每条线程都有且只有一个RunLoop[NSRunLoop currentRunLoop]类似于懒加载,如果当前线程没有RunLoop就创建一个RunLoop,如果线程有RunLoop就获得当前线程的RunLoop

2 .NSRunLoopCommonModesRunLoop的运行模式。RunLoop只能在一种运行模式下运行,如果切换运行模式,RunLoop会退出当前运行模式,进入另一个运行模式。系统默认注册5种运行模式,但是我们用到的3种分别是:

* NSDefaultRunLoopMode   //App的默认Mode,通常主线程是在这个Mode下运行

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


* NSRunLoopCommonModes   //这是一个伪模式,其为一组run loop mode的集合,将输入源加入此模式意味着在Common Modes中包含的所有模式下都可以处理

NSDefaultRunLoopMode是默认模式,当有ScrollView的滚动的时候,RunLoop会退出NSDefaultRunLoopMode模式,进入UITrackingRunLoopMode模式获得更流畅的滚动效果,如果将NSTimer放在NSDefaultRunLoopMode模式下面,那么当ScrollView滚动的时候,NSTimer将不会运行。

如果ScrollView停止滚动的时候,会从UITrackingRunLoopMode切换到NSDefaultRunLoopMode模式,如果将NSTimer放在UITrackingRunLoopMode模式下面,那么只有滚动ScrollView的时候,NSTimer才运行。

如果要要两种模式下面都运行NSTimer怎么办呢?当然,可以在两种Mode里面都加入NSTimer。另外一种方法,系统提供了CommonModes属性。如果将将NSTimer放入此模式下,那么任何模式下NSTimer都会运行

demo下载

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Run loop 剖析:Runloop 接收的输入事件来自两种不同的源:输入源(intput source)和定时...
    Mitchell阅读 12,515评论 17 111
  • 本文首发于我的个人博客:「程序员充电站」[https://itcharge.cn]文章链接:「传送门」[https...
    ITCharge阅读 60,992评论 50 541
  • RunLoop 文章目录 RunLoop简介 1.1 什么是RunLoop? 1.2 RunLoop和线程 1.3...
    May_d8f1阅读 305评论 0 1
  • 文章目录RunLoop简介1.1 什么是RunLoop? 1.2 RunLoop和线程1.3 默认情况下主线程的R...
    lusen_b阅读 405评论 0 2
  • 慢慢等,会来的,总会来的。 雷雨,狂风。萧萧,飒爽,吞噬。 站台,静等。匆匆,人群,褪淡。 午夜临,一丝亮光,车来...
    张某某T阅读 379评论 2 1