一.NSRunloop的基本认识
主线程Runlopp 从App开启,就一直存在(在main函数中初始化). 主线程的runloop :
[NSRunLoop mainRunLoop];
其他线程的 Runloop, 需要开发者自己手动去开启 :
[NSRunLoop currentRunLoop];
NSRunloop 既然和线程息息相关, 如果线程销毁或者 cancel , 则当前Runloop结束工作
NSRunLoop是保证线程不会退出,并且能在不处理消息的时候让线程休眠,节约资源,在接收到消息的时候唤醒线程做出对应处理的消息循环机制
-
NSRunloop 和 当前线程一一对应. 例如字典的 键值对, 可比喻成:
NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[@"mainThread"] = @"[NSRunLoop mainRunLoop]"; dict[@"thread1"] = @"RunLoop1"; dict[@"thread2"] = @"RunLoop2"; dict[@"thread3"] = @"RunLoop3"; dict[@"thread4"] = @"RunLoop4";
二.NSRunloop的本质
-
1.NSRunloop 本质上就是一个
do - while
循环do { var message = get_next_message(); process_message(message); } while (message != quit);
2.如果一直存在消息, 则一直循环去处理 消息,直到消息处理完毕,才跳出循环
三.NSRunloop的最常见使用 : NSTimer
同学们都在知道 在控制器中写入以下代码, 那么每隔3s都会执行一次指定的方法(这里先不考虑timer和self的引用)
NSTimer *timer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(excute) userInfo:nil repeats:true];
// 将timer 注册到 Runloop中
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
四.NSRunloop的Mode
NSDefaultRunLoopMode : 默认的模式
UITrackingRunLoopMode : 当滚动的时候会调用的模式
NSRunLoopCommonModes : (NSDefaultRunLoopMode 和 UITrackingRunLoopMode的组合)
...
62046-20170508103511988-278243544.png
- 1.
NSRunloop
中包含多个Mode
,每个Mode
中包含 :Source(Source0 , Source1)
Timer
Observer
- 2.每个Mode之间都是相对独立的,当切换
Mode
时必须退出当前Mode
,然后重新进入Runloop
以保证不同Mode的Source
Timer
Observer
互不影响。 - 3.实际运用:
NSRunLoopCommonModes
运用的较多. 原因: 一个纵向可滚动的scrollView上存放着3个横向滚动的 自动滚动轮播图,如果 轮播图中的timer添加的Mode
是NSDefaultRunLoopMode
或者UITrackingRunLoopMode
,那么我们手动拉动 ScrollView时, 轮播图是静止不动的,因为RunLoop
只有一个Mode
,无法进行切换. 如果添加的是NSRunLoopCommonModes
,那么当我没拉动scrollView时,RunLoop
在这两种Mode
之间不停的切换,保证了轮播图也可以正常滚动