什么是RunLoop
1.RunLoop從字面意思上看就是運(yùn)行循環(huán)润匙,其實(shí)它內(nèi)部就是一個(gè)do-while循環(huán)湃缎,在這個(gè)循環(huán)內(nèi)部不斷地處理各種任務(wù)(比如source枪萄,timer决侈,observer)。
2.一個(gè)線程只對(duì)應(yīng)一個(gè)RunLoop牵舱,主線程的RunLoop默認(rèn)是已經(jīng)開啟的串绩,子線程的RunLoop需要手動(dòng)開啟。開啟的方法如下:
[[NSRunLoop currentRunLoop] run];
總的來說RunLoop給我們的感覺就像應(yīng)用一直處于隨時(shí)待命的狀態(tài)芜壁,在沒人操作的時(shí)候它一直在休息礁凡,在讓它干活的時(shí)候高氮,它就能立刻響應(yīng)。
其實(shí)在進(jìn)行第一步通知Observer之前顷牌,RunLoop會(huì)檢查當(dāng)前Mode中有沒有Source剪芍,Timer,Observer窟蓝。如果有就會(huì)按上圖邏輯執(zhí)行罪裹。但是,RunLoop只能選擇一種Mode啟動(dòng)运挫,如果當(dāng)前Mode中沒有任何Source状共,Timer,Observer谁帕,那么就直接退出RunLoop峡继。
使用RunLoop的場(chǎng)景
那么我們通常怎么使用RunLoop進(jìn)行開發(fā)呢?
1.開啟一個(gè)常駐子線程(也就是說讓一個(gè)子線程不進(jìn)入消亡狀態(tài)匈挖,等待從其他線程發(fā)來的消息碾牌,處理其他事件)
// 在viewDidLoad中創(chuàng)建一個(gè)線程,并且開啟讓它執(zhí)行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]);
// 在當(dāng)前RunLoop(子線程)中添加一個(gè)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.在子線程中開啟定時(shí)器
3.在子線程中進(jìn)行一些長(zhǎng)期監(jiān)控小染。
4.可以控制定時(shí)器在特定模式下運(yùn)行翘瓮。
5.可以讓某些事情(行為贮折,任務(wù))在特定模式下執(zhí)行。
6.可以添加Observer監(jiān)聽RunLoop的狀態(tài)资盅,比如點(diǎn)擊事件的處理(在所有點(diǎn)擊事件之前做一些事情)