1、什么是RunLoop?
2、main函數(shù)為什么一直不退出呢捍岳?
3、RunLoop是怎么維護的循環(huán)?
什么是RunLoop?
RunLoop是通過內(nèi)部維護的一個事件循環(huán)來對事件/消息進行管理的一個對象锣夹。
目的是:
- 沒有消息處理時页徐,休眠以避免資源占用。同時會對線程由用戶態(tài)切換到內(nèi)核態(tài)银萍。
- 當有消息進行處理時变勇,立即被喚醒。 會對線程通內(nèi)核態(tài)到用戶態(tài)的切換贴唇,同時線程會被喚醒搀绣。
main函數(shù)為什么能保持不退出呢?
因為在main函數(shù)啟動后戳气,在內(nèi)部會調(diào)用UIApplicationMain函數(shù)链患,在這個函數(shù)內(nèi)部實際上會啟動主線程的一個運行循環(huán)即RunLoop,RunLoop可以接受一些事件/消息瓶您,并對這些事件/消息進行處理锣险,處理完之后再繼續(xù)進行等待,這里循環(huán)不單單的是一個while循環(huán)览闰,而是用戶態(tài)和內(nèi)核態(tài)之間的相互切換芯肤。
RunLoop是怎么維護的循環(huán)?
RunLoop是CFRunLoop的封裝压鉴,提供面向?qū)ο蟮腁PI崖咨。
在RunLoop中有五大類
- CFRunLoop
- CFRunLoopMode
- Source/Timer/Observer
CFRunLoop.png
其中
- source0 事件 需要手動喚醒線程
- source1 事件 具備喚醒線程的能力
CFRunLoopObserver
檢測時間點:
- kCFRunLoopEntry
- kCFRunLoopTimes
- kCFRunLoopObservers
- kCFRunLoopBeforeWaiting
- kCFRunLoopAfterWaiting
- kCFRunLoopExit
RunLoop與線程時一一對應(yīng)的關(guān)系,RunLoop與mode是一對多油吭,mode和Source/Timer/Observer是一對多
CFRunLoopMode.png
commonMode特殊性:
- commonMode
不是實際存在
的一種mode - 是同步Source/Timer/Observer到多個Mode的一種方案击蹲。
事件循環(huán)的實現(xiàn)機制
點擊App圖標,系統(tǒng)是如何進行啟動婉宰,休眠和退出的歌豺?
RunLoop事件循環(huán)機制.jpg
- 系統(tǒng)啟動后,會先執(zhí)行main函數(shù)
- 在main函數(shù)內(nèi)部會調(diào)用UIApplicationMain函數(shù)心包,啟動主線程的RunLoop
- 通知Observe將要處理Timer/Source0事件
- 處理source0事件
- 如果有source1事件要處理类咧,那么處理喚醒時收到的消息
- 如果沒有事件要處理了,通知observe線程進入休眠蟹腾,等待喚醒
- 當線程RunLoop接受到Source1痕惋,Timer事件或者外部手動喚醒,這時通過Mach-Port線程會被喚醒娃殖,從內(nèi)核態(tài)進入到用戶態(tài)值戳,處理事件
- 當線程退出時,會通知observe退出RunLoop
RunLoop核心
RunLoop核心.jpg