RunLoop問題簡單闡述

1、什麼是RunLoop?

  • 顧名思義:
    1、運行循環,在程序運行過程中循環做一些事情。
    2、iOS中有2套API來訪問和使用RunLoop
    √ Foundation:NSRunLoop
    √ Core Foundation:CFRunLoopRef
    3、NSRunLoop和CFRunLoopRef都代表着RunLoop對象
    4、NSRunLoop是基於CFRunLoopRef的一層OC包裝
    5、CFRunLoopRef是開源的

  • RunLoop的基本作用:
    1、保持程序的持續運行
    2、處理App中的各種事件(比如觸摸事件、定時器事件等)
    3、節省CPU資源,提高程序性能:該做事時做事,該休息時休息
    ......

  • CFRunLoopModeRef
    √ CFRunLoopModeRef代表RunLoop的運行模式
    √ 一個RunLoop包含若干個Mode,每個Mode又包含若干個Source0/Source1/Timer/Observer
    √ RunLoop啓動時只能選擇其中一個Mode,作爲currentMode
    √ 如果需要切換Mode,只能退出當前Loop,再重新選擇一個Mode進入
    √ 不同組的Source0/Source1/Timer/Observer能分隔開來,互不影響
    √ 如果Mode裏沒有任何Source0/Source1/Timer/Observer,RunLoop會立馬退出
    √ kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默認Mode,通常主線程是在這個Mode下運行
    √ UITrackingRunLoopMode:界面跟蹤 Mode,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響

  • 應用範疇:
    √ 定時器(Timer)、PerformSelector
    √ GCD Async Main Queue
    √ 事件響應、手勢識別、界面刷新
    √ 網絡請求
    √ AutoreleasePool

  • RunLoop在實際開中的應用
    √ 控制線程生命週期(線程保活)
    √ 解決NSTimer在滑動時停止工作的問題
    √ 監控應用卡頓
    √ 性能優化

2、RunLoop與線程關係?

  • 每條線程都有唯一的一個與之對應的RunLoop對象
  • RunLoop保存在一個全局的Dictionary裏,線程作爲key,RunLoop作爲value
  • 線程剛創建時並沒有RunLoop對象,RunLoop會在第一次獲取它時創建
  • RunLoop會在線程結束時銷燬
  • 主線程的RunLoop已經自動獲取(創建),子線程默認沒有開啓RunLoop

3、RunLoop的運行邏輯?

 

image


3.1、各種事件解析

 

  • Source0
    代碼斷點
    觸摸事件處理
    performSelector:onThread:

  • Source1
    基於Port的線程間通信
    系統事件捕捉

  • Timers
    NSTimer
    performSelector:withObject:afterDelay:

  • Observers
    用於監聽RunLoop的狀態
    UI刷新(BeforeWaiting)
    Autorelease pool(BeforeWaiting)

3.2、運行邏輯
01、通知Observers:進入Loop
02、通知Observers:即將處理Timers
03、通知Observers:即將處理Sources
04、處理Blocks
05、處理Source0(可能會再次處理Blocks)
06、如果存在Source1,就跳轉到第8步
07、通知Observers:開始休眠(等待消息喚醒)
08、通知Observers:結束休眠(被某個消息喚醒)
01> 處理Timer
02> 處理GCD Async To Main Queue
03> 處理Source1
09、處理Blocks
10、根據前面的執行結果,決定如何操作
01> 回到第02步
02> 退出Loop
11、通知Observers:退出Loop

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章