iOS學(xué)習(xí)筆記:RunLoop

原文鏈接:NSRunLoop簡(jiǎn)介

RunLoop的作用

  • 程序持續(xù)運(yùn)行的保證,如果RunLoop不存在了,程序也就結(jié)束運(yùn)行了。
  • 在循環(huán)中處理各種事件,如觸摸事件、定時(shí)器事件、Selector事件。
  • 節(jié)省CPU的資源,在需要執(zhí)行任務(wù)的時(shí)候被喚醒,當(dāng)沒(méi)有任務(wù)執(zhí)行的時(shí)候進(jìn)入休眠狀態(tài)。

程序啟動(dòng)的流程

  • 執(zhí)行main函數(shù)
  • 執(zhí)行UIApplicationMain函數(shù)
    • 指定UIApplication對(duì)象
    • 指定UIApplication的代理
  • 創(chuàng)建UIApplication對(duì)象,并且指定它的代理。
  • 創(chuàng)建一個(gè)主運(yùn)行循環(huán)(RunLoop),這是一個(gè)死循環(huán),保證程序的持續(xù)運(yùn)行。
  • 加載配置了所有應(yīng)用程序信息的info.plist文件
  • 應(yīng)用程序啟動(dòng)完畢

NSRunLoop和CFRunLoopRef

  • CFRunLoopRef是在CoreFoundation框架中的,它的內(nèi)部API以及實(shí)現(xiàn),都是純C語(yǔ)言編寫(xiě),這些API都是線程安全的。
  • NSRunLoop是基于CFRunLoopRef的封裝,它提供了面向?qū)ο蟮腁PI,但是這些API不是線程安全的。
  • 這兩個(gè)對(duì)象的地址不同,因?yàn)樗鼈兊膶?duì)象來(lái)自于完全不同的類(lèi)。
  • CFRunLoop可以調(diào)用getCfRunLoop方法,將NSRunLoop轉(zhuǎn)化為CFRunLoop。

RunLoop與線程

  • 每一條線程,都有一個(gè)與之相對(duì)應(yīng)的RunLoop對(duì)象,負(fù)責(zé)處理線程中的任務(wù)。
  • 主線程和RunLoop:RunLoop在程序已經(jīng)啟動(dòng)的時(shí)候就創(chuàng)建好了
  • 子線程和RunLoop:
    • 子線程會(huì)單獨(dú)開(kāi)啟RunLoop去執(zhí)行任務(wù)
    • 子線程和RunLoop是一一對(duì)應(yīng)的關(guān)系,每個(gè)子線程都有自己的RunLoop(但需要主動(dòng)創(chuàng)建)
    • 創(chuàng)建子線程的RunLoop:[NSRunloop currentRunLoop]
    • 子線程的RunLoop需要手動(dòng)開(kāi)啟:[[NSRunLoop currentRunLoop] run]

RunLoopMode

  • RunLoop的運(yùn)行模式

    • 一個(gè)RunLoop至少要指定一個(gè)運(yùn)行模式,當(dāng)運(yùn)行模式指定之后,至少有一個(gè)Source或者Timer任務(wù)在執(zhí)行。
    • RunLoop啟動(dòng)之后,只能指定一個(gè)運(yùn)行模式,可以使用currentMode來(lái)獲取。
    • 如果要切換RunLoop的運(yùn)行模式,就要先退出當(dāng)前的RunLoop,重新指定Mode再次進(jìn)入運(yùn)行。
  • 系統(tǒng)默認(rèn)注冊(cè)的5個(gè)Mode

    • kCFRunLoopDefaultMode App的默認(rèn)Mode,通常主線程是在這個(gè)Mode下運(yùn)行的。
    • UITrackingRunLoopMode 界面跟蹤Mode,用于ScrollView/TableView等追蹤觸摸滑動(dòng),保證界面滑動(dòng)的時(shí)候不受其他Mode影響。
    • UIInitializationRunLoopMode 當(dāng)App啟動(dòng)時(shí),第一個(gè)進(jìn)入的Mode,啟動(dòng)完成之后就不會(huì)再使用這個(gè)Mode。
    • GSEventReceiveRunLoopMode 接收系統(tǒng)事件的內(nèi)部Mode,通常由系統(tǒng)自動(dòng)管理。
    • kCFRunLoopCommonMode 一個(gè)類(lèi)似于占位的Mode,并不是一個(gè)真正的Mode。

CFRunLoopSourceRef:事件源、事件、輸入等都屬于事件源,它有兩個(gè)分類(lèi):

  • Source0 非基于Port的事件,用戶觸發(fā)的事件,例如點(diǎn)擊事件等。
  • Source1 基于Port的事件,他用于系統(tǒng)內(nèi)部與線程之間交互。

CFRunLoopTimerRef:定時(shí)器事件

  • NSTimer
    • 如果將NSTimer添加到子線程中,需要先創(chuàng)建一個(gè)RunLoop,然后再啟動(dòng)RunLoop。
    • NSTimer受到RunLoop的影響,一般會(huì)有一些輕微的誤差,所以對(duì)于精密計(jì)時(shí),GCD定時(shí)器較為精準(zhǔn)。
  • GCD定時(shí)器:精確到納秒,較為精準(zhǔn)。
    • GCD定時(shí)器的創(chuàng)建步驟:創(chuàng)建定時(shí)器 -> 設(shè)置定時(shí)器 -> 設(shè)置定時(shí)器的回調(diào)方法 -> 恢復(fù)定時(shí)器。
    • GCD定時(shí)器一定要添加一個(gè)強(qiáng)引用,否則會(huì)被立即釋放。

CFRunLoopObserverRef:觀察者

  • 觀察者可以觀察到RunLoop不同的運(yùn)行狀態(tài)
  • 通過(guò)判斷RunLoop的運(yùn)行狀態(tài),可以執(zhí)行一些操作。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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