iOS NSTimer引发的RunLoop

作者: 小沫360 | 来源:发表于2016-04-22 14:13 被阅读1284次

    作为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下载

    相关文章

      网友评论

      本文标题:iOS NSTimer引发的RunLoop

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