ios Runloop 詳細(xì)解析

? ? ? ? 關(guān)于Run Loops看了很多大神文章,還是有點(diǎn)云里霧里,所以有時(shí)間感覺還是有必要從概念入手,仔細(xì)啃一遍官方文檔。一起學(xué)習(xí)理解,有錯(cuò)誤的地方請(qǐng)指正。

RunLoop-概念

? ? ??Run Loops是一個(gè)事件處理循環(huán)機(jī)制,用于整合處理接收到的事件,它是IOS與線程相關(guān)的基礎(chǔ)架構(gòu)的一部分。Run Loops的主要職責(zé)是當(dāng)有事件需要處理的時(shí)候喚醒線程進(jìn)行處理,反之使線程處于休眠狀態(tài)。

? ? ? 每個(gè)線程都有一個(gè)相關(guān)聯(lián)的Run Loops對(duì)象,我們的程序不需要自己去創(chuàng)建。?Cocoa and Core Foundation都提供了相應(yīng)的接口幫助我們配置以及管理與線程相關(guān)聯(lián)的Run Loops,主線程的run loop是隨著程序啟動(dòng)的時(shí)候已經(jīng)自動(dòng)配置和啟動(dòng)的,其他線程的runloop需要我們自己手動(dòng)啟用。CFRunLoop 是Core Foundation 庫提供的runloop接口用C/C++實(shí)現(xiàn)的,是線程安全的,NSRunLoop是Foundation提供的接口用OC實(shí)現(xiàn),是對(duì)CFRunLoop的封裝,不是線程安全的,所以我們用NSRunLoop的對(duì)象處理runloop的時(shí)候需要避免在多線程處理。

RunLoop-原理

? ? ? ?Run Loops是一個(gè)循環(huán),線程啟動(dòng),借助runloop響應(yīng)處理輸入的事件,runloop的本質(zhì)就是借助while或者for控制語句實(shí)現(xiàn)的,在循環(huán)里面我們使用run loop 的對(duì)象接收事件以及執(zhí)行處理操作。

? ? ? ? Run Loops接收兩種不同的事件源,Input sourcesTimer sources。Input sources發(fā)送異步事件,比如線程之間的通信或者APP之間的通信。Timer sources發(fā)送同步事件,比如在預(yù)定的時(shí)間發(fā)生的事件或者重復(fù)發(fā)生的事件。對(duì)于Input sources我們可以通過Core Foundation 框架提供的接口注冊(cè)runloop的觀察者,當(dāng)runloop的行為發(fā)生改變我們可以收到通知,以此做一些需要的操作。runloop處理這兩種事件源都是按照程序指定的流程處理,如圖所示:

RunLoop-模式

? ? ? ?runloop模式是Input?sourcesTimer sources事件集合以及注冊(cè)觀察runloop的觀察者集合。我們運(yùn)行runloop都需要指定對(duì)應(yīng)的模式,當(dāng)我們指定某種模式,只有該模式相關(guān)聯(lián)的事件源會(huì)被監(jiān)聽并且允許其傳遞事件(類似的只有觀察了對(duì)應(yīng)模式的runloop才會(huì)收到,runloop的處理進(jìn)度)。其他模式的事件源只能等待適合的模式才能向runloop傳遞事件。Core Foundation框架提供了五種模式(NSDefaultRunLoopMode,NSConnectionReplyMode,NSModalPanelRunLoopMode,NSEventTrackingRunLoopMode,NSRunLoopCommonModes),我們這里只介紹三種常用的,如果有需要下次再更新。

1.NSDefaultRunLoopMode:默認(rèn)模式,大多數(shù)時(shí)候我們使用這個(gè)模式啟動(dòng)runloop和配置input sources,比如我們創(chuàng)建的定時(shí)器默認(rèn)就是該模式。

2.NSEventTrackingRunLoopMode:字面意思就是事件追蹤模式,該模式監(jiān)聽鼠標(biāo)拖動(dòng)(手指拖動(dòng))以及其他類型的用戶交互追蹤。比如當(dāng)我們滑動(dòng)表的時(shí)候就會(huì)觸發(fā)該模式下的runloop。

3.NSRunLoopCommonModes:這個(gè)模式是一個(gè)常用模式的組合,在Foundation框架下該模式包含NSDefaultRunLoopMode和NSEventTrackingRunLoopMode,在Core Foundation下只包含NSDefaultRunLoopMode,我們可以使用CFRunLoopAddCommonMode函數(shù)將自定義模式添加到該集合。指定這種模式就相當(dāng)于指定了該模式組合下的所有模式。

我們何時(shí)需要使用RunLoop?

? ?你可能用到runloop的地方是當(dāng)你創(chuàng)建子線程的時(shí)候,但是并不是所有的子線程都需要開啟runloop,比如你開始一個(gè)子線程執(zhí)行一個(gè)復(fù)雜耗時(shí)的任務(wù)或者一個(gè)預(yù)先設(shè)定好的任務(wù),此時(shí)我們都不需要開啟runloop,很多時(shí)候runloop是用于線程間的通訊的。官方總結(jié)了以下幾點(diǎn)我們會(huì)使用到runloop的地方:

1.當(dāng)我們使用端口或者自定義的input sources與其他線程交互的時(shí)候。

2.在線程中使用定時(shí)器。

3.在程序中使用任何的performSelector… 方法。

4.讓線程執(zhí)行定期的任務(wù)

RunLoop使用注意事項(xiàng)

? ? ? ? 開啟runloop有三種方法,1.不加任何限制的開啟,2設(shè)定一個(gè)限定時(shí)間,3.指定一種模式。一個(gè)runloop至少需要監(jiān)視一個(gè)input source或者一個(gè)定時(shí)器,否則runloop會(huì)立即退出。第一種開啟的方法是最簡(jiǎn)單的但是也是最不可取的,因?yàn)檫@種方法是不可控制。第二種方法和第三種方法可以混合使用,而且是比較推薦使用的。

? ? ? ?退出runloop有兩種方式:1.當(dāng)我們以限定時(shí)間開啟一個(gè)runloop時(shí),時(shí)間結(jié)束,runloop就會(huì)退出,2.手動(dòng)停止,調(diào)用Core Foundation提供的CFRunLoopStop函數(shù)。雖然移除input source或者定時(shí)器會(huì)使runloop退出,但是很多時(shí)候,我們的代碼不能正真的移除input source或者定時(shí)器,而這些會(huì)阻止runloop退出。

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 翻譯來源: RunLoops Run Loops RunLoops是與線程緊密相關(guān)的基礎(chǔ)架構(gòu)的一部分,簡(jiǎn)稱運(yùn)行循環(huán)...
    AlexCorleone閱讀 683評(píng)論 0 1
  • Run Loops 下面會(huì)用一些陌生的或者容易讓人混淆的字符,我們先來統(tǒng)一概念再繼續(xù),這樣能夠讓你更加愉快的閱讀:...
    董二千閱讀 683評(píng)論 0 1
  • 什么是Run Loops RunLoops是與線程相關(guān)聯(lián)的基礎(chǔ)部分,一個(gè)Run Loop就是事件處理循環(huán),他是用來...
    傻傻小蘿卜閱讀 1,103評(píng)論 0 5
  • 先貼下 apple doc, 本文基本是對(duì)照 doc 的翻譯:https://developer.apple.co...
    brownfeng閱讀 7,119評(píng)論 8 111
  • 醒來之后,便開始尋找。 你在屋子那個(gè)地方,心情瞬間失落。 想到你并不在身旁,可這感覺如此美妙! 卻又讓人感傷,開始...
    年少知無閱讀 287評(píng)論 0 0

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