RunLoop,跑圈。在iOS开发中,也就是运行循环。
在应用需要的时候自己跑起来运行,在用户没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。
二. RunLoop的概念与作用
概念:一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。
例如一个应用放那里,不进行操作就像静止休息一样,点击按钮,就有响应,就像“随时待命”一样,这就是RunLoop的功劳。
所以RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行RunLoop 的逻辑。
线程开始这个函数之后,便一直会处于此函数 "接受消息->等待->处理" 的循环中:(有事:做出反应; 木事:休眠省电; 再次有事:重新唤醒、处理事件。)
直到这个循环结束(比如传入 quit 的消息),最后函数返回。
作用:
- 保持程序持续运行:例如程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行;
- 处理App中的各种事件(比如:触摸事件,定时器事件,Selector事件等 );
- 节省CPU资源,优化程序性能:程序运行起来时,当什么操作都没有做的时候,RunLoop就通知系统,现在没有事情做,然后进行休息待命状态,这时系统就会将其资源释放出来去做其他的事情。当有事情做,也就是一有响应的时候RunLoop就会立马起来去做事情;
RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。
当线程的RunLoop一开启,RunLoop便开始对线程进行管理工作:在线程执行完任务后,线程便会进入休眠状态,并且不会退出,随时等待新的任务。
三、RunLoop与线程的关系
1.每条线程都有唯一的一个与之对应的RunLoop对象;
2.RunLoop在第一次获取时创建,在线程结束时销毁;只能在一个线程的内部获取其 RunLoop(主线程除外)。
3.主线程的RunLoop系统默认启动,子线程的RunLoop需要主动开启;
其实在我们每次建立项目的时候,就已经使用上了RunLoop。
(这里只是粗略的知识点,主要的看下面截图)
只有主线程的消息循环默认开启,子线程的消息循环默认不开启
(个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行)
消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行
UITrackingRunLoopMode 当滚动scrollView的时候,消息循环的模式会改变成这种
使用消息循环的时候必须指定两件事情
1 . 输入事件:输入源和定时源
2 . 消息循环的模式
eg:
// 这里的self,是selector里面的方法的所属对象
// userInfo 是方法跟的参数
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES];
//把定时器添加到当前线程消息循环中 这个就是定时源的模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
currentRunLoop 当前的消息循环吧
***********
- (void)demo {
//输出当前消息循环的模式
NSLog(@"%@",[NSRunLoop currentRunLoop].currentMode);
}
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 这里的self,是selector里面的方法的所属对象
// userInfo 是方法跟的参数
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES];
//把定时器添加到当前线程消息循环中 这个就是定时源的模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
// (个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行)
//消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行
//UITrackingRunLoopMode 当滚动scrollView的时候,消息循环的模式会改变成这种
}
- (void)demo {
//输出当前消息循环的模式
NSLog(@"hello %@",[NSRunLoop currentRunLoop].currentMode);
}
@end