iOS面試 -- RunLoop

1. 什么是 RunLoop?

通過系統(tǒng)內(nèi)部維護的事件循環(huán)進行事件/消息管理的一個對象就是 runloop
特點:

  • 沒有消息需要處理時,休眠避免資源占用
    狀態(tài)切換: 用戶態(tài)->內(nèi)核態(tài),有消息處理時,就是用戶態(tài)的消息處理,而沒有消息時,就托管到系統(tǒng)內(nèi)核本身進行處理
  • 有消息需要處理時,立刻被喚醒
    狀態(tài)切換:內(nèi)核態(tài)->用戶態(tài)
    用戶態(tài):應用程序一般是運行在用戶態(tài)
    內(nèi)核態(tài):當我們發(fā)生系統(tǒng)調(diào)用的時候則是在內(nèi)核態(tài)
    為什么有用戶態(tài)和內(nèi)核態(tài)?
    是因為計算機為了更好的進行資源分配以及調(diào)度,而使系統(tǒng)達到最佳的資源利用,故產(chǎn)生了用戶態(tài)和內(nèi)核態(tài)

為什么 main 函數(shù)能夠保持一直存在且不退出?

在 main 函數(shù)內(nèi)部會調(diào)用 UIApplicationMain 這樣一個函數(shù),而在UIApplicationMain內(nèi)部會啟動主線程的 runloop,因為 runloop 就是通過系統(tǒng)內(nèi)部維護的事件循環(huán)進行事件/消息管理的一個對象,因為可以做到有消息處理時,能夠迅速從內(nèi)核態(tài)到用戶態(tài)的切換,立刻喚醒處理,而沒有消息處理時通過用戶態(tài)到內(nèi)核態(tài)的切換進入等待狀態(tài),避免資源占用。因此 main 函數(shù)能夠一直存在且不退出。

在 OC中系統(tǒng)為我們提供了哪幾種 runloop?

NSRunloop(Foundation),CFRunloop(CoreFoundation)

CFRunloop 的數(shù)據(jù)結(jié)構(gòu)

  • CFRunloop
  • CFRunloopMode
  • Source/Timer/Observer

CFRunloop

  • pthread
  • currentMode
  • modes
  • commonModes
  • commonModeItems

pthread

  • 代表線程,線程和 runloop 是一一對應的
    currentMode
  • CFRunloopMode
    modes
  • 表示的是一個CFRunloopMode的集合
    commonModes
  • 也是一個集合,只是它是一個String 的集合

commonModeItems

  • 也是一個集合,里面包含多個 source,多個 timer,多個 observer

CFRunloopMode

  • name 當前 mode的名稱
  • sources0 集合
  • sources1 集合
  • observers 數(shù)組
  • timers 數(shù)組

CFRunloopSource

  • source0 需要手動喚醒線程
  • source1 具備主動喚醒線程的能力

CFRunloopTimer
和 NSTimer 是可以免費橋接的

CFRunloopObserver

  • 觀測時間點
  • kCFRunloopEntry
  • kCFRunloopBeforeTimers
  • kCFRunloopBeforeSources
  • kCFRunloopBeforeWaiting (通知對應觀察者當前 runloop 將要進入休眠狀態(tài)了,系統(tǒng)將從用戶態(tài)切換到內(nèi)核態(tài))
  • kCFRunloopAfterWaiting
  • kCFRunloopExit

runloop 和 model 以及 source 、 timer、observer 的關(guān)系?

如圖,這是一個一對多的關(guān)系


runloop 的 mode


如圖,runloop 中可以存在多個 mode,每個 mode中有多個 source,observe以及多個 timers,當我們的 runloop 運行在某個 mode中時, 是相互獨立且互不干擾的,當 mode2 中的runloop 接收到回到時,我們運行在 mode 中的 runloop 是不能響應的。

滑動 tableView 的時候,timer 定時器失效了,為什么?

因為 UITableView 的 runloop 默認情況下是運行在 kCFRunloopDefaultMode中,當我們滑動的時候mode切換到UITrackingRunloopMode 中的,而定時器也是運行在 kCFRunloopDefaultMode 中,對應的 observer、timer是沒有辦法進行處理的,所以 timer 會失效,如何解決呢??梢酝ㄟ^ CFRunloopAddTimer函數(shù)把 timer 的 runloop 添加到 commonrunloopmode中,CFRunloopCurrentModes 是系統(tǒng)提供一個將當前 runloopmode添加到多個 mode 的方法,這不是一個真正意義存在的 mode,他是同步 source、observer、timer 到多個 mode 的一種技術(shù)解決方案,當我們調(diào)用CFRunloopAddTimer的時候,系統(tǒng)是會把我們創(chuàng)建的timer同步到UITrackingRunloopMode中的 timers 里面,因此當 tabview 滑動的時候,發(fā)生 mode 的切換,我們的 timer 依舊可以生效。

當一個休眠狀態(tài)的 runloop 我們可以通過哪些方式喚醒?

  • timer事件
  • source1
  • 外部手動喚醒

runloop 事件循環(huán)機制內(nèi)部流程

怎么樣實現(xiàn)一個常駐線程?(三步走)

  • 為當前線程添加一個 runloop
  • 向添加的 runloop添加一個 port/source 等維持 runloop 的事件循環(huán)
  • 啟動 runloop
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Runloop是iOS和OSX開發(fā)中非?;A(chǔ)的一個概念,從概念開始學習。 RunLoop的概念 -般說,一個線程一...
    小貓仔閱讀 1,109評論 0 1
  • 轉(zhuǎn)自bireme,原地址:https://blog.ibireme.com/2015/05/18/runloop/...
    乜_啊_閱讀 1,682評論 0 5
  • 轉(zhuǎn)自http://blog.ibireme.com/2015/05/18/runloop 深入理解RunLoop ...
    飄金閱讀 1,084評論 0 4
  • 原文地址:http://blog.ibireme.com/2015/05/18/runloop/ RunLoop ...
    大餅炒雞蛋閱讀 1,266評論 0 6
  • 所里今天安排學生朋友來參觀,有小朋友問:我最多加班到晚上九點就到身體極限了,怎么辦? 此問題顯然被他的前輩們鄙視了...
    知識管理某李閱讀 492評論 2 4

友情鏈接更多精彩內(nèi)容