本文是拜讀 http://blog.ibireme.com/2015/05/18/runloop/ 后的一些個(gè)人見(jiàn)解. 想更加深入地了解請(qǐng)猛戳上面的鏈接.
RunLoop,翻譯過(guò)來(lái),就是一個(gè)不斷循環(huán)的閉環(huán).這個(gè)閉環(huán)不斷地處理任務(wù). 具體流程是處理任務(wù)-休眠-被喚醒處理任務(wù).正如餐廳服務(wù)員可以響應(yīng)客人的需求,在客人不需要服務(wù)的時(shí)候在門(mén)外守候,直到再次被召喚.
事實(shí)上,RunLoop就是一個(gè)對(duì)象,這個(gè)對(duì)象管理了其需要處理的事件和消息,并提供了一個(gè)入口函數(shù)來(lái)執(zhí)行一個(gè)doWhile函數(shù),不斷處理任務(wù).線(xiàn)程執(zhí)行了這個(gè)函數(shù)后,就會(huì)一直處于這個(gè)函數(shù)內(nèi)部 "接受消息->等待->處理" 的循環(huán)中,直到這個(gè)循環(huán)結(jié)束(比如傳入 quit 的消息),函數(shù)返回.還是舉餐廳的例子,一旦客人進(jìn)來(lái)餐廳,餐廳就要負(fù)責(zé)調(diào)配服務(wù)員處理客人的要求,直到客人用餐完畢離開(kāi).
我們什么時(shí)候會(huì)需要用到RunLoop呢?
在回答這個(gè)問(wèn)題之前,我們得知道更多的信息,其實(shí),每一個(gè)線(xiàn)程都是對(duì)應(yīng)一個(gè)RunLoop的,但是除了主線(xiàn)程的RunLoop,其他RunLoop默認(rèn)是不開(kāi)啟的.只有我們主動(dòng)獲取他的時(shí)候,才會(huì)開(kāi)啟.
要了解RunLoop,我們必須知道兩個(gè)對(duì)象:
1,CFRunLoopRef是在Core Foundation里面的,它是一套純C的API,是線(xiàn)程安全的.
2,NSRunLoop則是對(duì)CFRunLoopRef的封裝,它是面對(duì)對(duì)象的API,不是線(xiàn)程安全的.
由于NSRunLoop并不是開(kāi)源的,我們只能通過(guò)CFRunLoopRef來(lái)研究.通過(guò)http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz](http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz可以下載源代碼.
RunLoop 與線(xiàn)程的關(guān)系
首先,iOS 開(kāi)發(fā)中能遇到兩個(gè)線(xiàn)程對(duì)象: pthread_t 和 NSThread。過(guò)去蘋(píng)果有份文檔標(biāo)明了 NSThread 只是 pthread_t 的封裝,但那份文檔已經(jīng)失效了,現(xiàn)在它們也有可能都是直接包裝自最底層的 mach thread。蘋(píng)果并沒(méi)有提供這兩個(gè)對(duì)象相互轉(zhuǎn)換的接口,但不管怎么樣,可以肯定的是 pthread_t 和 NSThread 是一一對(duì)應(yīng)的。比如,你可以通過(guò) pthread_main_np() 或 [NSThread mainThread] 來(lái)獲取主線(xiàn)程;也可以通過(guò) pthread_self() 或 [NSThread currentThread] 來(lái)獲取當(dāng)前線(xiàn)程。CFRunLoop 是基于 pthread 來(lái)管理的。
蘋(píng)果不允許直接創(chuàng)建 RunLoop,它只提供了兩個(gè)自動(dòng)獲取的函數(shù):CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。