中高級iOS必備知識點-RunLoop

RunLoop學(xué)習(xí)起來是很抽象,也不好理解,所以一定多看幾次,多學(xué)學(xué)才能學(xué)好!這也是中高級iOS必須掌握的知識點,面試中經(jīng)常遇到.


什么是 RunLoop继榆?

Run 表示運(yùn)行,Loop 表示循環(huán)共屈。結(jié)合在一起就是運(yùn)行循環(huán)的意思。RunLoop就是在程序運(yùn)行過程中循環(huán)做一些事情.

RunLoop的應(yīng)用范疇有哪些?

定時器(Timer)、PerformSelector

GCD Async Main Queue

事件響應(yīng)捞稿、手勢識別、界面刷新

網(wǎng)絡(luò)請求

AutoreieasePool

上面這些底層都是RunLoop在支撐,說白了,如果沒有RunLoop支撐,上面的這些都無法實現(xiàn).

如果沒有RunLoop會發(fā)生什么呢?像我們的命令行項目,創(chuàng)建出來默認(rèn)就是沒有RunLoop,請看下圖

因為沒有RunLoop,程序執(zhí)行到第13行的時候,就會自動退出.

而我們iOS項目的main函數(shù)里面都有UIApplicationMain(argc, argv,nil, appDelegateClassName);這個代碼,這里就是創(chuàng)建了一個主線程的RunLoop,所以我們程序不會退出,一直在運(yùn)行中.我們可以大致寫一下main函數(shù)里面的偽代碼如下:

retVal這個等于0,當(dāng)沒有事件處理的時候,RunLoop就會sleep就是類似睡覺,一旦有事件需要處理,比如點擊钝尸、刷新事件等process_message就會去處理這個事件,處理完了繼續(xù)休息,retVal=0,程序就會一直執(zhí)行,不會退出,這就是RunLoop作用.

作為一個開發(fā)者括享,有一個學(xué)習(xí)的氛圍跟一個交流圈子特別重要,這是一個我的iOS開發(fā)交流群:130 595 548珍促,不管你是小白還是大牛都?xì)g迎入駐 铃辖,讓我們一起進(jìn)步,共同發(fā)展V硇稹(群內(nèi)會免費(fèi)提供一些群主收藏的免費(fèi)學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔=空丁)

RunLoop的基本作用

1.保持程序的持續(xù)運(yùn)行

2.處理App中的各種事件(比如觸摸事件、定時器事件等)

3.節(jié)省了CPU資源,提高程序性能:該做事時做事,該休息時休息

...

獲取RunLoop對象

iOS中有2套API來訪問和使用RunLoop :

Foundation : NSRunLoop (OC語言里面的)

Core Foundation : CFRunLoopRef (C語言里面的)

NSRunLoop和CFRunLoopRef都代表著RunLoop對象

NSRunLoop是基于CFRunLoopRef的一層OC包裝

CFRunLoopRef是開源的.(CFRunLoopRef參考鏈接)

其實我們很多都是由OC包裝出來的,請看下面:

獲取當(dāng)前的RunLoop

獲取當(dāng)前RunLoop和主線程RunLoop

獲取RunLoop

這里注意,地址不一樣,因為NSRunLoop是對CFRunLoopDef做了一層包裝,你可以用OC的NSLog("%@",[NSRunLoop MainRunLoop])獲取對比一下,它的地址就是C語言獲取的地址.主線程只有一個RunLoop.

RunLoop與線程

每條線程都有唯一的一個與之對應(yīng)的RunLoop對象(一一對應(yīng))

RunLoop保存在一個全局的Dictionary里,線程作為key,RunLoop作為value

線程剛創(chuàng)建的時候并沒有RunLoop對象,RunLoop會在第一次獲取它時創(chuàng)建

RunLoop會在線程結(jié)束時銷毀

主線程的RunLoop已經(jīng)自動創(chuàng)建,子線程默認(rèn)沒有開啟RunLoop.

源碼窺探看一下:CFRunLoopGetCurrent

由于源碼不能像objc直接打開,我們把它拉到項目中查看.

從字典也能看出來是一對一的關(guān)系.而且確實是第一次獲取的時候是空的,然后再去創(chuàng)建這個RunLoop.

那我們就繼續(xù)來了解RunLoop內(nèi)部的數(shù)據(jù)結(jié)構(gòu),到底是怎么工作的.

RunLoop相關(guān)的類

Core Foundation中關(guān)于RunLoop的5個類

1.CFRunLoopRef

2.CFRunLoopModeRef

3.CFRunLoopSourceRef

4.CFRunLoopTimerRef

5.CFRunLoopObserverRef

再看下CFRunLoopRef的底層源碼:

就是上面這個結(jié)構(gòu)體,我們用到的可能就是紅色這些.pthread是線程,每個runloop都會保存這個東西.最后面那個_modes,這個是個集合來著,CFMutableSetRef我們能想到我們自己用的set也是一個集合來著,比如NSMutableSet也是一個集合,所以這個_modes里面是存著一堆的mode.

這個mode就是CFRunLoopModeRef類型,所以里面存儲一堆的CFRunLoopModeRef類型的mode.

而_currentMode也是CFRunLoopModeRef這個類型,所以我們很容易得出一個結(jié)論:

一個RunLoop對象里面有一堆的mode,也就是存在_modes里面,里面只有一個是_currentMode.

我們再窺探一下源碼,看下mode里面存儲的是什么?

所以我們來個總結(jié)的圖:

RunLoop有很多種模式,對應(yīng)的_currentMode只有一種.

CFRunLoopModeRef

1.CFRunLoopModeRef它是代表RunLoop的運(yùn)行模式

2.一個RunLoop包含若干個Mode,每個Mode又包含若干個Source0/Source1/Timer/Observer

3.RunLoop啟動時只能選擇其中一個Mode,作為currentMode

4.如果需要切換Mode,只能退出當(dāng)前RunLoop,再重新選擇一個Mode進(jìn)入

5.不同組的Source0/Source1/Timer/Observer能分割開來,互不影響

6.如果Mode里面沒有任何Source0/Source1/Timer/Observer,RunLoop會立馬退出

如果只能在一種模式下運(yùn)行,對性能什么的都有很大好處,比如我在滑動模式下,不考慮不滑動的模式,所以就不會卡頓,順暢很多.還有注意的就是,它切換mode是在循環(huán)里面切換的,所以不會導(dǎo)致程序退出.

常見的mode有2種,其他情況很少見,所以掌握這兩個一般都是沒問題了

1.KCFRunLoopDefaultMode (NSDefaultRunLoopMode):App的默認(rèn)Mode,通常是主線程是在這個Mode下運(yùn)行

2.UITrackingRunLoopMode : 界面跟蹤Mode,用于ScrollView追蹤觸摸滑動,保證界面滑動時不受其他Mode影響

RunLoop到底做哪些事?

RunLoop在不停執(zhí)行的時候到底具體做了哪些事?其實是RunLoop在不停循環(huán)的時候,就是處理每個mode下的Source0穴翩、Source1犬第、Timer、Observer這里面的事件,那我們就來看看這里面具體對應(yīng)的到底是什么事件.

Source0

觸摸事件芒帕、performSelector:onThread:

比如我們的touchbegin這個我們看下下面的代碼:

Source1

基于Port的線程間的通信,系統(tǒng)事件的捕捉.

(兩個線程之間相互傳遞消息的處理,系統(tǒng)事件捕捉,其實也包括觸摸事件,只是把事件捕捉到以后傳遞給Source0).

Timer

NSTimer定時器,performSelector:withObject:afterDelay(這個方法的底層實現(xiàn)也就是NSTimer來實現(xiàn)的)

Observers

用于監(jiān)聽RunLoop的狀態(tài),UI的刷新(BeforeWaiting),Autorelease pool(BeforeWaiting)

(在RunLoop休眠之前都會去執(zhí)行UI的刷新啊歉嗓、Autorelease pool的釋放等)

以上這些東西,完全就是我們平時開發(fā)中經(jīng)常寫的代碼,比如設(shè)置背景色,設(shè)置frame等等.

由于RunLoop知識點比較多,如果寫太多不利于大家的閱讀和消化,所以其他內(nèi)容放在后面介紹!

如果覺得我寫得對您有所幫助,請關(guān)注我背蟆,我會持續(xù)更新??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鉴分,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子带膀,更是在濱河造成了極大的恐慌志珍,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垛叨,死亡現(xiàn)場離奇詭異伦糯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門敛纲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喂击,“玉大人,你說我怎么就攤上這事载慈〔训龋” “怎么了珍手?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵办铡,是天一觀的道長。 經(jīng)常有香客問我琳要,道長寡具,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任稚补,我火速辦了婚禮童叠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘课幕。我一直安慰自己厦坛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布乍惊。 她就那樣靜靜地躺著杜秸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪润绎。 梳的紋絲不亂的頭發(fā)上撬碟,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音莉撇,去河邊找鬼呢蛤。 笑死,一個胖子當(dāng)著我的面吹牛棍郎,可吹牛的內(nèi)容都是我干的其障。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涂佃,長吁一口氣:“原來是場噩夢啊……” “哼励翼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起巡李,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤抚笔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后侨拦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殊橙,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了膨蛮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叠纹。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖敞葛,靈堂內(nèi)的尸體忽然破棺而出誉察,到底是詐尸還是另有隱情,我是刑警寧澤惹谐,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布持偏,位于F島的核電站,受9級特大地震影響氨肌,放射性物質(zhì)發(fā)生泄漏鸿秆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一怎囚、第九天 我趴在偏房一處隱蔽的房頂上張望卿叽。 院中可真熱鬧,春花似錦恳守、人聲如沸考婴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沥阱。三九已至,卻和暖如春颗圣,著一層夾襖步出監(jiān)牢的瞬間喳钟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工在岂, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留奔则,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓蔽午,卻偏偏與公主長得像易茬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子及老,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容