RunLoop 三: 執行流程圖
一、 回顧 新增 Observer 監聽 RunLoop 的所有狀態
-
新增 Observer 可以監聽到 RunLoop 的各種狀態
-
kCFRunLoopEntry: 進入 RunLoop 迴圈
-
kCFRunLoopBeforeTimers: 處理 定時器(Timers)
-
kCFRunLoopBeforeSources: 處理 Sources
-
kCFRunLoopBeforeWaiting: 休眠之前
-
kCFRunLoopAfterWaiting: 被喚醒
-
kCFRunLoopExit: 退出當前 RunLoop
-
一般來說:從當前 RunLoop 切換到 另外一個 RunLoop;
-
它會先退出當前 RunLoop 的模式,在進入新的模式
二、回顧 RunLoop 中 mode 的內部結構
(有個大概印象,面試前鞏固下)(瞭解)
- Sources0
- Sources1
- Timers
- Observers
三、回顧 專案中的 RunLoop
- 在 專案的main.m 中只有一句程式碼,這句程式碼就是 RunLoop 的執行程式碼。
- UIApplicationMain 方法中會建立 RunLoop 物件,會執行一些 RunLoop 的流程。
- 上面圖片的程式碼 執行的大概過程 如圖三:
- 重複的(迴圈的)做一些事情
- 比如:在睡眠中 等待訊息,如果有訊息了,就會醒過來處理訊息。訊息處理完畢,接著睡覺。(一直重複)
- 例如:螢幕是黑色的(這是睡眠中),如果有人點選了螢幕。螢幕就會亮起來(這就是處理訊息,或者處理點選事件,點選事件是屬於Source1)
四、 蘋果官方的 RunLoop 執行邏輯圖
無非就是進入某一種模式,把模式的 sources0,sources1,Timers,Observers 拿出來執行。
- 解釋上邊圖片中左側部分的圖片
- 左邊的 thread 圖片是 執行緒圖片。在這個圖片中有一個 黃色的迴圈圈。可以認為這個迴圈圈就是RunLoop所要做的事情。
- 黃色的圈主要做了:
- handlePort: 處理埠 ( 埠 -> sources1) 可能是別的執行緒發的一些訊息。執行緒跟執行緒的互動一般通過埠的形式。
- customSrc:自定義的源(自定義sources)
- mySelector:處理 selector,如
performSelector:onThread:
- timerFired:定時器
- 解釋上邊圖片中右側部分的圖片
- 上邊圖片中左側部分的圖片中要做的事情是 外界的一些源給的。
五、RunLoop 具體做的事情(掌握)
01、通知Observers:進入Loop
* RunLoop 在進入迴圈之前,首先會發出一個通知,告訴監聽器,要進入 Loop 了。
02、通知Observers:即將處理Timers
03、通知Observers:即將處理Sources
* 比如: Sources0、Sources1
04、處理Blocks
* RunLoop 執行我們新增 一些 block
CFRunLoopPerformBlock("runLoop", "runLoop的模式", ^{ NSLog(@"block 程式碼塊"); })
05、處理Source0(可能會再次處理Blocks)
06、如果存在Source1,就跳轉到第8步
07、通知Observers:開始休眠(等待訊息喚醒)
* 如果沒有 Source1 就代表沒有事情做,才會走這步。
08、通知Observers:結束休眠(被某個訊息喚醒)
01> 處理Timer
02> 處理GCD Async To Main Queue
03> 處理Source1
04> 誰喚醒的,處理誰。比如 定時器喚醒的,就處理 timer。
09、處理Blocks
10、根據前面的執行結果,決定如何操作
01> 回到第02步
02> 退出Loop
11、通知Observers:退出Loop