什么是runloop?
運(yùn)行循環(huán) 。 如果沒有runloop 程序執(zhí)行完畢后就會(huì)立即退出,如果有程序就會(huì)一直運(yùn)行,且時(shí)刻等待用戶輸入操作。runloop可以在需要時(shí)進(jìn)行,沒有操作時(shí)休息節(jié)省cpu資源,提高程序性能
了解了RunLoop,那么它什么時(shí)候開始工作呢?
UIApplicationMain函數(shù)內(nèi)啟動(dòng)了Runloop,程序不會(huì)馬上退出,而是保持運(yùn)行狀態(tài)。因此每一個(gè)應(yīng)用必須要有一個(gè)runloop, 我們知道主線程一開起來,就會(huì)跑一個(gè)和主線程對(duì)應(yīng)的RunLoop,那么RunLoop一定是在程序的入口main函數(shù)中開啟
RunLoop 內(nèi)部 由 do while判斷進(jìn)行類似于死循環(huán)所以可以保證程序一直進(jìn)行
RunLoop的作用
1 保持程序的持續(xù)運(yùn)行 程序一啟動(dòng)就會(huì)開一個(gè)主線程,就會(huì)相應(yīng)的跑一個(gè)runloop來保證主線程不會(huì)被銷毀,也保證了程序的持續(xù)運(yùn)行 2 處理App的各種事件 比如觸摸,selector,定時(shí)器 3 節(jié)省cpu資源,提高程序性能
RunLoop和線程間的關(guān)系
1 每條線程都有唯一的一個(gè)與之對(duì)應(yīng)的runloop對(duì)象
2 RunLoop保存在一個(gè)全局的 Dictionary里,線程作為key,RunLoop作為value
3 主線程的RunLoop已經(jīng)自動(dòng)創(chuàng)建好了,子線程的RunLoop需要主動(dòng)創(chuàng)建 RunLoop在第一次獲取時(shí)創(chuàng)建,在線程結(jié)束時(shí)銷毀
線程和 RunLoop 之間是一一對(duì)應(yīng)的,其關(guān)系是保存在一個(gè) Dictionary 里。所以我們創(chuàng)建子線程RunLoop時(shí),只需在子線程中獲取當(dāng)前線程的RunLoop對(duì)象即可[NSRunLoop currentRunLoop];如果不獲取,那子線程就不會(huì)創(chuàng)建與之相關(guān)聯(lián)的RunLoop,并且只能在一個(gè)線程的內(nèi)部獲取其 RunLoop [NSRunLoop currentRunLoop];方法調(diào)用時(shí),會(huì)先看一下字典里有沒有存子線程相對(duì)用的RunLoop,如果有則直接返回RunLoop,如果沒有則會(huì)創(chuàng)建一個(gè),并將與之對(duì)應(yīng)的子線程存入字典中。當(dāng)線程結(jié)束時(shí),RunLoop會(huì)被銷毀
RunLoop 內(nèi)部實(shí)現(xiàn)
RunLoop 結(jié)構(gòu)體看源碼可以知道里面有兩個(gè)比較重要的成員變量
其實(shí)是指向__CFRunLoopMode結(jié)構(gòu)體的指針,__CFRunLoopMode結(jié)構(gòu)體,其中有以下成員變量
CFRunLoopModeRef代表RunLoop的運(yùn)行模式,一個(gè)RunLoop包含若干個(gè)Mode,每個(gè)Mode又包含若干個(gè)Source0/Source1/Timer/Observer,而RunLoop啟動(dòng)時(shí)只能選擇其中一個(gè)Mode作為currentMode。
Source0:觸摸事件
Source1:基于port的線程間通信
Timer: 定時(shí)器,NSTimer
Observer : 監(jiān)聽器,用于監(jiān)聽RunLoop的狀態(tài)
系統(tǒng)默認(rèn)的五個(gè)model
Mode間的切換
我們肯定遇到過這樣的問題 當(dāng)我們使用NSTimer每一段時(shí)間執(zhí)行一些事情時(shí)滑動(dòng)UIScrollView,NSTimer就會(huì)暫停,當(dāng)我們停止滑動(dòng)以后,NSTimer又會(huì)重新恢復(fù)的情況
真正的原因是什么呢?
NSTimer不管用是因?yàn)镸ode的切換,因?yàn)槿绻覀冊(cè)谥骶€程使用定時(shí)器,此時(shí)RunLoop的Mode為kCFRunLoopDefaultMode,即定時(shí)器屬于kCFRunLoopDefaultMode,那么此時(shí)我們滑動(dòng)ScrollView時(shí),RunLoop的Mode會(huì)切換到UITrackingRunLoopMode,因此在主線程的定時(shí)器就不在管用了,調(diào)用的方法也就不再執(zhí)行了,當(dāng)我們停止滑動(dòng)時(shí),RunLoop的Mode切換回kCFRunLoopDefaultMode,所以NSTimer就又管用了。
還有就是回到主線程加載圖片,滑動(dòng)scrollview 也不加載了,是因?yàn)閜erformSelector默認(rèn)是在default模式下運(yùn)行,因此在滑動(dòng)ScrollView時(shí),圖片不會(huì)加載
總結(jié)一下runloop的過程

相關(guān)文章 http://www.itdecent.cn/p/de752066d0ad