
文章插圖
RunLoop 學(xué)習(xí)起來是很抽象,也不好理解,所以一定多看幾次,多學(xué)學(xué)才能學(xué)好!這也是中高級 iOS 必須掌握的知識點(diǎn),面試中經(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 支撐,上面的這些都無法實(shí)現(xiàn) 。
如果沒有 RunLoop 會發(fā)生什么呢?像我們的命令行項(xiàng)目,創(chuàng)建出來默認(rèn)就是沒有 RunLoop,請看下圖
因?yàn)闆]有 RunLoop,程序執(zhí)行到第 13 行的時候,就會自動退出.
而我們 iOS 項(xiàng)目的 main 函數(shù)里面都有 UIApplicationMain(argc, argv, nil, appDelegateClassName);這個代碼,這里就是創(chuàng)建了一個主線程的 RunLoop,所以我們程序不會退出,一直在運(yùn)行中 。我們可以大致寫一下 main 函數(shù)里面的偽代碼如下:
retVal 這個等于 0,當(dāng)沒有事件處理的時候,RunLoop 就會 sleep 就是類似睡覺,一旦有事件需要處理,比如點(diǎn)擊、刷新事件等 process_message 就會去處理這個事件,處理完了繼續(xù)休息,retVal=0,程序就會一直執(zhí)行,不會退出,這就是 RunLoop 作用 。
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 參考鏈接)
其實(shí)我們很多都是由 OC 包裝出來的,請看下面:
獲取當(dāng)前的 RunLoop
獲取當(dāng)前 RunLoop 和主線程 RunLoop
獲取 RunLoop
這里注意 “地址不一樣” 因?yàn)?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 直接打開,我們把它拉到項(xiàng)目中查看 。
從字典也能看出來是一對一的關(guān)系 。而且確實(shí)是第一次獲取的時候是空的,然后再去創(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 。
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請您及時就醫(yī)或請專業(yè)人士給予相關(guān)指導(dǎo)!
「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對您有所幫助:- 詳解word單獨(dú)刪除某一頁 在word2013怎么刪除空白頁
- 二 四十二式太極拳教學(xué)圖文詳解
- 一 四十二式太極拳教學(xué)圖文詳解
- 四 四十二式太極拳教學(xué)圖文詳解
- 三 四十二式太極拳教學(xué)圖文詳解
- 太極拳24式1-4式圖片詳解
- 太極劍劍法招式要點(diǎn)詳解
- 詳解陳氏太極拳的特性
- 養(yǎng)生太極拳 詳解武當(dāng)太極拳九式
- linux下壓縮文件夾命令 linux zip命令詳解
