大家好,我是面試聊iOS的程序員专钉。
這篇文章將和大家分享面試iOS時聊RunLoop一般都可以聊些什么娘荡。
抖音搜索 面試聊iOS 觀看視頻版
相關文章鏈接
面試聊iOS:內(nèi)存管理
面試聊iOS:RunTime(一)
面試聊iOS:RunTime(二)
面試聊iOS:Block
面試聊iOS:多線程
面試聊iOS:RunLoop
面試聊iOS:性能優(yōu)化
什么是RunLoop
默認情況下干旁,線程執(zhí)行完任務后就會退出,不再執(zhí)行任務炮沐。我們需要采用一種方式來讓線程能夠不斷的處理任務争群,并且不退出,所有就有了RunLoop大年。
顧名思義换薄,RunLoop就是一直運行著的循環(huán)。
RunLoop實際上是一個對象翔试,這個對象在循環(huán)中用來處理程序運行過程中出現(xiàn)的各種事件(比如說touch事件轻要、UI刷新事件、定時器事件垦缅、Selector事件)冲泥,從而保持程序的持續(xù)運行。Runloop在沒有事件處理時壁涎,會讓線程進入休眠凡恍,只有在接收到事件時才會被喚醒,然后再做出相應的處理怔球。
一條線程對應一個RunLoop對象嚼酝,主線程的RunLoop對象由系統(tǒng)自動創(chuàng)建。
RunLoop Mode
NSDefaultRunLoopMode
app默認Mode竟坛,通常主線程就在該Mode下運行闽巩。
NSTrackingRunLoopMode
界面跟蹤mode,用于scrollView追蹤觸摸滑動担汤,保證界面滑動時不受其他Mode影響涎跨。
UIInitializationRunLoopMode
在剛啟動app時進入的第一個Mode,啟動完成后就不再使用崭歧。
GSEventReceiveRunLoopMode
接收系統(tǒng)事件的內(nèi)部Mode六敬,通常用不到。
NSRunLoopCommonModes
這是一個占位Mode驾荣,不是一個真正的Mode,會同時處理默認模式和UI模式中的事件普泡。
RunLoop Source
定時源播掷,基于時間的觸發(fā)器,基本上就是NSTimer
NSTimer默認被加入RunLoop的default mode下
source0:非基于Port的源撼班,基本就是應用層事件歧匈,比如點擊事件
source1:基于Port的源,通過內(nèi)核和其他線程通信砰嘁,接收件炉、分發(fā)系統(tǒng)事件
我們點擊app內(nèi)的某個按鈕勘究,先觸摸到屏幕(硬件),屏幕表面的事件會先封裝成Event傳遞給source1(mach_port)斟冕,source1喚醒runloop口糕,讓后將Event分發(fā)給source0處理。
RunLoop Observer
CFRunLoopObserverRef磕蛇,監(jiān)聽RunLoop的狀態(tài)改變
即將進入Loop:1
即將處理Timer:2
即將進入source:4
即將進入休眠:32
即將從休眠中喚醒:64
即將從Loop中退出:128
監(jiān)聽全部狀態(tài)改變
RunLoop運行邏輯
- 通知觀察者即將進入RunLoop
- 通知觀察者即將處理Timer
- 通知觀察者即將處理source0
- 處理source0
- 如果有source1景描,跳至第9步
- 通知觀察者線程即將進入休眠狀態(tài)
- 線程進入休眠,等待直到以下任一事件發(fā)生喚醒線程
- 某一事件到達基于端口的源
- 定時器啟動
- RunLoop設置的時間超時
- RunLoop被顯式喚醒
- 通知觀察者線程即將被喚醒
- 處理喚醒時收到的事件
- 如果用戶定義的定時器啟動秀撇,處理定時器事件并重啟RunLoop超棺,跳回步驟2;
- 如果輸入源啟動呵燕,傳遞相應消息棠绘;
- 如果RunLoop被顯式喚醒且時間未超時,重啟RunLoop再扭,跳回步驟2
- 通知觀察者氧苍,即將退出RunLoop
常駐線程
如果經(jīng)常會在子線程中做一些耗時操作(比如下載文件、后臺播放音樂等)霍衫,最好能讓這條線程常駐內(nèi)存
為當前線程添加一個RunLoop
向該RunLoop中添加一個Port/Source等維持RunLoop的事件循環(huán)
啟動該RunLoop