作为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 .NSRunLoopCommonModes
是RunLoop
的运行模式。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
都会运行
网友评论