Runloop的作用
Runloop準(zhǔn)確來說控制的是線程的休眠和喚醒,是一套使線程持續(xù)運行的機制(而不是一下子跑完就沒了)Runloop常見疑問
- Runloop是如何喚醒的?
進入休眠后,并不是自己喚醒的,都是要借助外力(也就是其他線程換起的)。如觸摸事件,系統(tǒng)將觸摸封裝成事件,并且通過進程之間端口通訊傳遞到我們的進程。包括我們所熟知的定時器事件,必然也是系統(tǒng)給告訴我們的進程。 - 界面卡頓
為什么界面卡頓?就是CPU和GPU渲染工作未完成,在屏幕刷新信號時,由于界面未渲染完成,顯示的還是上一張界面,所以看起來會卡頓。當(dāng)然在這里也有Runloop的原因,就是在每一次屏幕刷新之間,盡量耗時任務(wù)盡量移動到子線程執(zhí)行,無法移動的,盡量分成多個小任務(wù)。
- Runloop如何運作?
- 存在輸入源,才能啟動Runloop,否則直接退出,往后執(zhí)行。
- 運行模式,其實只是將事件運行的環(huán)境進行分類。每次Runloop都會運行在指定的模式,只有當(dāng)前模式的事件,才會觸發(fā)。假設(shè)當(dāng)前運行模式是A,而添加了一個定時器到模式B,那么只有當(dāng)Runloop運行到模式B,那么定時器才會執(zhí)行。
- Runloop退出的條件是什么?①移除所有輸入源 ②主動停止Runloop
- Runloop支持線程喚醒的事件類型
-
基于端口的事件
如觸摸事件,系統(tǒng)將觸摸事件封裝,并且通過進程之間端口通訊傳遞到我們的進程。[[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes]; -
自定義事件
[self performSelector:@selector(taskDo) onThread:thread withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]]; -
基于時間的定時事件
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
- Runloop的應(yīng)用
- UI在什么時候渲染?
我們先來看一段。
會不會閃一下?答案是不會的。因為UI不是立即渲染的,CA在runloop中注冊了一個即將進入休眠的observer,在休眠之前對已提交的請求進行集中渲染。self.view.hidden = YES; ...... self.view.hidden = NO; - 界面卡頓問題
卡頓問題,一次runloop繪制任務(wù)太多仍會存在卡頓問題,放到下個Runloop,以減少單次runloop繪制任務(wù)。(其實重用UI、子線程處理耗時的非UI操作基本上能處理大多數(shù)常見卡頓)。runloop中將一個任務(wù)放到第二次runloop中執(zhí)行。最簡單使用[self performSelector:@selector(xxxxx) withObject:nil afterDelay:0],而GCD的話,是不一定的。 - 第三方動態(tài)化框架RN、Weex等
這些框架能否都跑在主線程?可以是可以,但是由于流暢性考慮,都是管理自己的線程,自己的Runloop。最簡單的就是,添加一個NSPort?;睿缓笾苯优芫涂梢粤?。一些熱更新呢等處理,可以考慮停止線程、Runloop,釋放很多的內(nèi)存。
- UI在什么時候渲染?