iOS RunLoop 總結以及相關面試題解答
Runloop
Runloop
是事件接收和分發機制的一個實現。是執行緒相關的基礎框架的一部分。一個Runloop就是一個事件處理的迴圈,用來不停的排程工作及處理輸入事件。使用runloop的目的就是讓你的執行緒
RunLoop
的主要目的:
保證程式執行的執行緒不會被系統終止,如果沒有RunLoop,UIApplicationMain函式執行完畢之後將直接返回,就是說程式一啟動然後就結束,在有工作的時候忙於工作,而沒有工作的時候處於休眠狀態,
複製程式碼
什麼時候使用Runloop
?
當需要和該執行緒進行互動的時候才會使用Runloop.
複製程式碼
Runloop Mode
一個Runloop
可能有幾個mode
Runloop Mode
實際上是 Source,Timer 和 Observer 的集合,不同的 Mode 把不同組的
Source,
Timer和
Observer隔絕開來。
Runloop` 在某個時刻只能跑在一個 Mode 下,處理這一個 Mode 當中的 Source,Timer 和 Observer。
蘋果文件中提到的 Mode 有五個,分別是:
NSDefaultRunLoopMode
:預設的mode,正常情況下都是在這個mode NSConnectionReplyMode
NSModalPanelRunLoopMode
NSEventTrackingRunLoopMode
NSRunLoopCommonModes
iOS 中公開暴露出來的只有 NSDefaultRunLoopMode
和 NSRunLoopCommonModes
。 NSRunLoopCommonModes
實際上是一個 Mode 的集合,預設包括 NSDefaultRunLoopMode
和 NSEventTrackingRunLoopMode
。
Source
即可以喚醒Runloop
的一些事件。比如使用者點選了螢幕,就會建立一個input source。
source0
: 非系統事件source1
Timer
我們經常用的NSTimer
就屬於這一類。
Observer
某個observer可以監聽runloop
的狀態變化,並作出一定反應。
RunLoop執行流程
經典大圖
沒有事情的時候,Runloop
處於休眠狀態。當外部source將其喚醒後,它會依次處理接收到的timer/source,然後再次進入休眠。
常見的面試題:
Runloop
和執行緒是什麼關係?
每條執行緒都有唯一的一個與之對應的RunLoop物件;主執行緒的RunLoop已經自動建立,子執行緒的RunLoop需要主動建立;RunLoop在第一次獲取時建立,線上程結束時銷燬
Runloop
的mode作用是什麼?
指定事件在執行迴圈中的優先順序的,
執行緒的執行需要不同的模式,去響應各種不同的事件,去處理不同情境模式。(比如可以優化tableview的時候可以設定UITrackingRunLoopMode下不進行一些操作,比如設定圖片等。)
以+scheduledTimerWithTimeInterval:
的方式觸發的timer
,在滑動頁面上的列表時,timer
會暫停回撥, 為什麼?
滑動scrollView時,主執行緒的
RunLoop
會切換到UITrackingRunLoopMode
這個Mode,執行的也是UITrackingRunLoopMode
下的任務(Mode中的item),而timer是新增在NSDefaultRunLoopMode
下的,所以timer任務並不會執行,只有當UITrackingRunLoopMode
的任務執行完畢,runloop切換到NSDefaultRunLoopMode
後,才會繼續執行timer。
如何解決在滑動頁面上的列表時,timer會暫停回撥?
將
Timer
放到NSRunLoopCommonModes
中執行即可
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
複製程式碼
NSTImer
使用時需要注意什麼?
- 注意timer新增到runloop時應該設定為什麼mode
- 注意timer在不需要時,一定要呼叫invalidate方法使定時器失效,否則得不到釋放