Runloop

作用(作用重大)

保持程序的持續(xù)運行--內(nèi)部就是do-while循環(huán),在這個循環(huán)內(nèi)部不斷地處理各種任務(wù)

(比如Source、Timer囱修、Observer)

處理app中的各種事件(比如觸摸事件外傅、定時器事件【NSTimer】、selector事件

【選擇器·performSelector···】)

節(jié)省CPU資源荒勇,提高程序性能,有事情就做事情闻坚,沒事情就休息

重要說明

Runloop是程序一直存在并不斷處理事件的原因

main函數(shù)中的Runloop

a. 在UIApplication函數(shù)內(nèi)部就啟動了一個Runloop 該函數(shù)返回一個int類型的值

b. 默認(rèn)啟動的Runloop是跟主線程相關(guān)聯(lián)的

Runloop對象

在iOS開發(fā)中有兩套api來訪問Runloop

a. foundation框架【NSRunloop】

b. core foundation框架【CFRunloopRef】

c. NSRunLoop和CFRunLoopRef都代表著RunLoop對象,它們是等價的沽翔,可以互相轉(zhuǎn)換

d. NSRunLoop是基于CFRunLoopRef的一層OC包裝,所以要了解RunLoop內(nèi)部結(jié)構(gòu)窿凤,需要多研究

CFRunLoopRef層面的API(Core Foundation層面)

Runloop與線程

Runloop和線程的關(guān)系:一個Runloop對應(yīng)著一條唯一的線程仅偎,一條線程最多有一個Runloop西潘;開啟一個Runloop能讓子線程不死

Runloop的創(chuàng)建:主線程Runloop已經(jīng)創(chuàng)建好了,子線程的runloop需要手動創(chuàng)建并開啟

Runloop的生命周期:在第一次獲取時創(chuàng)建哨颂,在線程結(jié)束時銷毀

獲得Runloop對象

1.獲得當(dāng)前Runloop對象

//01 NSRunloop

NSRunLoop * runloop1 = [NSRunLoop currentRunLoop];

//02 CFRunLoopRef

CFRunLoopRef runloop2 =? CFRunLoopGetCurrent();

?

2.拿到當(dāng)前應(yīng)用程序的主Runloop(主線程對應(yīng)的Runloop)

//01 NSRunloop

NSRunLoop * runloop1 = [NSRunLoop mainRunLoop];

//02 CFRunLoopRef

CFRunLoopRef runloop2 =? CFRunLoopGetMain();

?

/*3.注意點:開一個子線程創(chuàng)建runloop,不是通過alloc init方法創(chuàng)建喷市,而是直接通過調(diào)用

currentRunLoop方法來創(chuàng)建,它本身是一個懶加載的威恼。如果不存在那么會自動創(chuàng)建一個該線程

對應(yīng)的runloop對象返回

4.在子線程中品姓,如果不主動獲取Runloop的話,那么子線程內(nèi)部是不會創(chuàng)建Runloop的箫措「贡福可以下載

CFRunloopRef的源碼,搜索_CFRunloopGet0,查看代碼斤蔓。

5.Runloop對象是利用字典來進行存儲植酥,而且key是對應(yīng)的線程Value為該線程對應(yīng)的Runloop。

*/

基本應(yīng)用

/*

1)開啟NSTimer弦牡,控制定時器在特定模式下執(zhí)行

2)可以讓某些事件(行為友驮、任務(wù))在特定模式下執(zhí)行,如ImageView顯示:控制方法在特定的模式下可用

3)PerformSelector:控制線程執(zhí)行不同的任務(wù)

4)常駐線程:讓一個子線程不進入消亡狀態(tài)驾锰,等待其他線程發(fā)來消息卸留,處理其他事件

5)可以添加Observer監(jiān)聽RunLoop的狀態(tài),比如監(jiān)聽點擊事件的處理(在所有點擊事件之前做一些事情

6)自動釋放池(可通過Observer監(jiān)聽RunLoop的狀態(tài))

第一次創(chuàng)建:進入runloop的時候

最后一次釋放:runloop退出的時候

其它創(chuàng)建和釋放:當(dāng)runloop即將休眠的時候會把之前的自動釋放池釋放椭豫,然后重新創(chuàng)建一個新的釋放池

?

常駐線程實現(xiàn):

主線程對應(yīng)的runloop默認(rèn)已經(jīng)創(chuàng)建好了,但是子線程對應(yīng)的runloop需要手動創(chuàng)建

子線程對應(yīng)的runloop還需要手動的開啟耻瑟,否則該runloop一創(chuàng)建出來就退出;在開啟前要先添加事件赏酥,否則也會退出喳整。

保證mode里面有事件,不讓runloop立刻退出

可以往runloop中添加source和timer,但是添加observer是沒有作用的

*/

/*

NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timer) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

*/

?

//創(chuàng)建子線程對應(yīng)的runloop并添加基于port的source

[[NSRunLoop currentRunLoop]addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

?

//開啟runloop,運行在默認(rèn)模式下面(添加timer或是port都要開始runloop)

[[NSRunLoop currentRunLoop]run];


請簡單說明runloop中幾個類之間的相互關(guān)系(runloop & source & timer &observer &mode)

a.CFRunloopRef

b.CFRunloopModeRef【Runloop的運行模式】

c.CFRunloopSourceRef【Runloop要處理的事件源】

d.CFRunloopTimerRef【Timer事件】

e.CFRunloopObserverRef【Runloop的觀察者(監(jiān)聽者)】

1.runloop啟動之后會選擇一種運行模式,在執(zhí)行執(zhí)行會先檢查運行模式內(nèi)部是否有source和timers,如果一個sourc或者是一個timer都沒有那么runlooop啟動之后就立刻退出了裸扶。

2.runlooop的source有兩種分類方法

按照以前的分類方法可以分為: 基于端口的? 自定義的? performSelector事件

按照函數(shù)調(diào)用棧來劃分:? source0? soucrce1

3.observer框都,可以用來監(jiān)聽當(dāng)前runloop運行狀態(tài)的改變,注意(Core foundation框架)

4.NSTimer必須添加到runloop中才會工作姓言,且其工作收到runloop運行模式的影響瞬项。defultMode? UItrackingMode

什么時候使用run loop

僅當(dāng)在為你的程序創(chuàng)建輔助線程的時候,你才需要顯式運行一個run loop何荚。Run loop是程序主線程基礎(chǔ)設(shè)施的關(guān)鍵部分。所以猪杭,Cocoa和Carbon程序提供了代碼運行主程序的循環(huán)并自動啟動run loop餐塘。IOS程序中UIApplication的run方法(或Mac OS X中的NSApplication)作為程序啟動步驟的一部分,它在程序正常啟動的時候就會啟動程序的主循環(huán)皂吮。類似的戒傻,RunApplicationEventLoop函數(shù)為Carbon程序啟動主循環(huán)税手。如果你使用xcode提供的模板創(chuàng)建你的程序,那你永遠(yuǎn)不需要自己去顯式的調(diào)用這些例程需纳。

對于輔助線程芦倒,你需要判斷一個run loop是否是必須的。如果是必須的不翩,那么你要自己配置并啟動它兵扬。你不需要在任何情況下都去啟動一個線程的run loop。比如口蝠,你使用線程來處理一個預(yù)先定義的長時間運行的任務(wù)時器钟,你應(yīng)該避免啟動run loop。Run loop在你要和線程有更多的交互時才需要妙蔗,比如以下情況:

使用端口或自定義輸入源來和其他線程通信

使用線程的定時器

Cocoa中使用任何performSelector…的方法

使線程周期性工作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末傲霸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子眉反,更是在濱河造成了極大的恐慌昙啄,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寸五,死亡現(xiàn)場離奇詭異跟衅,居然都是意外死亡,警方通過查閱死者的電腦和手機播歼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門伶跷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秘狞,你說我怎么就攤上這事叭莫。” “怎么了烁试?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵雇初,是天一觀的道長。 經(jīng)常有香客問我减响,道長靖诗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任支示,我火速辦了婚禮刊橘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘颂鸿。我一直安慰自己促绵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著败晴,像睡著了一般浓冒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尖坤,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天稳懒,我揣著相機與錄音,去河邊找鬼慢味。 笑死场梆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贮缕。 我是一名探鬼主播辙谜,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼感昼!你這毒婦竟也來了装哆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤定嗓,失蹤者是張志新(化名)和其女友劉穎蜕琴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宵溅,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡凌简,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了恃逻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雏搂。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖寇损,靈堂內(nèi)的尸體忽然破棺而出凸郑,到底是詐尸還是另有隱情,我是刑警寧澤矛市,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布芙沥,位于F島的核電站,受9級特大地震影響浊吏,放射性物質(zhì)發(fā)生泄漏而昨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一找田、第九天 我趴在偏房一處隱蔽的房頂上張望歌憨。 院中可真熱鬧,春花似錦午阵、人聲如沸躺孝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽植袍。三九已至,卻和暖如春籽懦,著一層夾襖步出監(jiān)牢的瞬間于个,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工暮顺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厅篓,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓捶码,卻偏偏與公主長得像羽氮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惫恼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

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