RunLoop是iOS中的一種重要機(jī)制,那什么是runLoop,runLoop到底有什么價(jià)值吶?接下來給大家做一個(gè)簡單的介紹.
1.什么是RunLoop
RunLoop是線程相關(guān)的的基礎(chǔ)框架的一部分喻粹。一個(gè)RunLoop就是一個(gè)事件處理的循環(huán)嘱根,用來不停的調(diào)度工作以及處理輸入事件。使用RunLoop的目的是讓你的線程在有工作的時(shí)候忙于工作,而沒工作的時(shí)候處于休眠狀態(tài).RunLoop實(shí)質(zhì)就是do...while循環(huán)
2.RunLoop存在的意義
第一保持程序的持續(xù)運(yùn)行,第二處理app的各種事件(觸摸事件,定時(shí)器事件),第三節(jié)省CPU資源,提高程序性能 該做事做事該休息休息(程序在睡覺)
3.RunLoop剖析
iOS 中有提供了兩套api來訪問和使用RunLoop 一個(gè)是Foundation(OC語言 NSRunLoop )? 一個(gè)是CoreFoundation(C 語言CFRunLoopRef),NSRunLoop是對(duì) CFRunLoopRef的進(jìn)一步封裝,想要更深層次的研究RunLoop就要去研究CFRunLoopRef,RunLoop主要處理與線程的交互事件,每一個(gè)線程都有唯一的一個(gè)與之對(duì)應(yīng)的RunLoop對(duì)象,主線程的RunLoop已經(jīng)自動(dòng)創(chuàng)建好了,子線程的RunLoop需要手動(dòng)創(chuàng)建.
CoreFoundation與RunLoop相關(guān)的類比較底層有一下幾個(gè)
CFRunLoopSourceRef
CFRunLoopTimerRef
CFrRunLoopObserverRef
CFRunLoopModeRef?
CFRunLoopRef
它們的關(guān)系如下圖
首先介紹一下CFRunLoopModeRef,CFRunLoopModeRef是RunLoop中的一種運(yùn)行模式,系統(tǒng)默認(rèn)注冊了5種Mode,在這里我們最常用到的是NSDefaultRunLoopMode,UITrackingRunLoopMode.NSDefaultRunLoopMode是App默認(rèn)的Mode,通常主線程是在這個(gè)Mode下運(yùn)行的,UITrackingRunLoopMode是界面跟蹤Mode,用于ScollView追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(shí)不受其他Mode影響. 一個(gè)RunLoop包含了若干個(gè)mode,每一個(gè)Mode有包含了若干個(gè)CFRunLoopSourceRef/CFRunLoopTimerRef/CFrRunLoopObserverRef.在這里有多個(gè)Mode主要是為了分隔開不同組source/timer/observer讓其互不影響,每一個(gè)RunLoop啟動(dòng)時(shí)只能指定其中一個(gè)Mode,這個(gè)Mode被稱作CurrentMode.如果需要切換Mode,只能退出Loop,再重新指定一個(gè)Mode進(jìn)入.
接下來創(chuàng)建一個(gè)定時(shí)器,在界面上添加一個(gè)ScollView,當(dāng)滑動(dòng)ScollView的時(shí)候觀察定時(shí)器的輸出
換一種Mode滑動(dòng)ScollView,滑動(dòng)的時(shí)候輸出,停止滑動(dòng)的時(shí)候不打印
系統(tǒng)并沒有提供UITrackingRunLoopMode,但是提供了NSRunLoopCommonModes,換成NSRunLoopCommonModes觀察滑動(dòng)不滑動(dòng)都會(huì)走run方法,NSRunLoopCommonModes并不是運(yùn)行模式,它只是一種標(biāo)簽,將UITrackingRunLoopMode與NSDefaultRunLoopMode都標(biāo)記為NSRunLoopCommonModes
CFRunLoopSourceRef 是事件產(chǎn)生的地方官套。Source有兩個(gè)版本:Source0 和 Source1。
Source0 只包含了一個(gè)回調(diào)(函數(shù)指針)衷笋,它并不能主動(dòng)觸發(fā)事件酣溃。使用時(shí),你需要先調(diào)用 CFRunLoopSourceSignal(source)栓撞,將這個(gè) Source 標(biāo)記為待處理遍膜,然后手動(dòng)調(diào)用 CFRunLoopWakeUp(runloop) 來喚醒 RunLoop,讓其處理這個(gè)事件瓤湘。
Source1 包含了一個(gè) mach_port 和一個(gè)回調(diào)(函數(shù)指針)瓢颅,被用于通過內(nèi)核和其他線程相互發(fā)送消息。這種 Source 能主動(dòng)喚醒 RunLoop 的線程弛说,其原理在下面會(huì)講到挽懦。
CFRunLoopObserverRef 是觀察者,當(dāng) RunLoop 的狀態(tài)發(fā)生變化時(shí)木人,觀察者就能通過回調(diào)接受到這個(gè)變化信柿。可以觀測的時(shí)間點(diǎn)有以下幾個(gè):
為RunLoop添加即將進(jìn)入休眠時(shí)候的監(jiān)聽
RunLoop 的內(nèi)部邏輯