原文鏈接:https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=400417748&idx=1&sn=0c5f6747dd192c5a0eea32bb4650c160&3rd=MzA3MDU4NTYzMw==&scene=6#rd
1、iOS RunLoop都干了什么
RunLoop是一個接收處理異步消息事件的循環,一個循環中:等待事件發生,然后將這個事件送到能處理它的地方。
RunLoop主要處理以下6類事件:
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__();
static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__();
①Observer事件,runloop中狀態變化時進行通知。(微信卡頓監控就是利用這個事件通知來記錄下最近一次main runloop活動時間,在另一個check線程中用定時器檢測當前時間距離最后一次活動時間過久來判斷在主線程中的處理邏輯耗時和卡主線程)。這里還需要特別注意,CAAnimation是由RunloopObserver觸發回調來重繪,接下來會講到。
②Block事件,非延遲的NSObject PerformSelector立即調用,dispatch_after立即調用,block回調。
③Main_Dispatch_Queue事件:GCD中dispatch到main queue的block會被dispatch到main loop執行。
④Timer事件:延遲的NSObject PerformSelector,延遲的dispatch_after,timer事件。
⑤Source0事件:處理如UIEvent,CFSocket這類事件。需要手動觸發。觸摸事件其實是Source1接收系統事件后在回調 __IOHIDEventSystemClientQueueCallback() 內觸發的 Source0,Source0 再觸發的 _UIApplicationHandleEventQueue()。source0一定是要喚醒runloop及時響應并執行的,如果runloop此時在休眠等待系統的 mach_msg事件,那么就會通過source1來喚醒runloop執行。
⑥Source1事件:處理系統內核的mach_msg事件。(推測CADisplayLink也是這里觸發)。