什么是RunLoop
1.RunLoop从字面意思上看就是运行循环,其实它内部就是一个do-while循环,在这个循环内部不断地处理各种任务(比如source,timer,observer)。
2.一个线程只对应一个RunLoop,主线程的RunLoop默认是已经开启的,子线程的RunLoop需要手动开启。开启的方法如下:
[[NSRunLoop currentRunLoop] run];
总的来说RunLoop给我们的感觉就像应用一直处于随时待命的状态,在没人操作的时候它一直在休息,在让它干活的时候,它就能立刻响应。
其实在进行第一步通知Observer之前,RunLoop会检查当前Mode中有没有Source,Timer,Observer。如果有就会按上图逻辑执行。但是,RunLoop只能选择一种Mode启动,如果当前Mode中没有任何Source,Timer,Observer,那么就直接退出RunLoop。
使用RunLoop的场景
那么我们通常怎么使用RunLoop进行开发呢?
1.开启一个常驻子线程(也就是说让一个子线程不进入消亡状态,等待从其他线程发来的消息,处理其他事件)
// 在viewDidLoad中创建一个线程,并且开启让它执行run方法。
- (void)viewDidLoad {
[super viewDidLoad];
self.thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
[self.thread start];
}
- (void)run{
NSLog(@"*********run*********%@",[NSRunLoop currentRunLoop]);
// 在当前RunLoop(子线程)中添加一个Source(Source是基于Port的)
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
// 开启RunLoop
[[NSRunLoop currentRunLoop] run];
NSLog(@"**********************");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}
- (void)test{
NSLog(@"********test********%@", [NSThread currentThread]);
}
2.在子线程中开启定时器
3.在子线程中进行一些长期监控。
4.可以控制定时器在特定模式下运行。
5.可以让某些事情(行为,任务)在特定模式下执行。
6.可以添加Observer监听RunLoop的状态,比如点击事件的处理(在所有点击事件之前做一些事情)