RunLoop總結(jié)

什么是RunLoop

Runloop視頻
這個視頻講得很好,看完收獲很大屡立,對RunLoop有概念了褂痰,并且了解了一些應(yīng)用亩进。尤其是前面那個子線程timer的例子,一步一步遞進(jìn)缩歪,容易理解归薛,建議多看幾遍。
從這個例子開始了解匪蝙,創(chuàng)建計時器:
主線程添加計時器

主線程添加計時器

上面的scheduledTimerWithTimeInterval是對下面的封裝主籍。是添加到NSRunLoop的默認(rèn)模式,還是要用下面的方式創(chuàng)建加timer逛球。

子線程添加計時器

  • 一條線程的生命只能由它的任務(wù)保住千元,讓線程有執(zhí)行不完的任務(wù),線程就不會釋放了颤绕。
  • 一條線程上面的RunLoop默認(rèn)是不循環(huán)的幸海,要手動run起來。[[NSRunLoop currentRunLoop] run]死循環(huán)奥务,和while(true)一樣物独,但是更多內(nèi)容。
  • 執(zhí)行currentRunLoop() 第一次獲取RunLoop的時候才創(chuàng)建氯葬,屬于懶加載挡篓。
  • 暴力退出線程 [NSThread exit];



CFRunLoopRun的偽代碼 Runloop培訓(xùn)視頻有講解
兩小時二十五分鐘開始聽比較好。

__CFRunLoopRun {
    do {
        __CFRunLoopDoBlocks 處理 block
        __CFRunLoopDoSources0 處理 source0
        if (判斷是否有其他消息需要處理帚称,如果有) {
            goto: handler_msg(處理消息模塊)
        }
        __CFRunLoopServiceMachPort(wait) 準(zhǔn)備休眠 阻塞 // 如果有消息來了官研,需要處理就醒了
       handle_msg: (處理消息模塊:timer, gcd, __CFRunLoopDoSource1)

    } while(1)
}

從字面上看

  • 運行循環(huán)
  • 跑圈

基本作用

  • 保持程序的持續(xù)運行(比如主運行循環(huán))
  • 處理APP中的各種事件(比如觸摸事件秽澳、定時器事件、Selector事件)
  • 節(jié)省CPU資源戏羽,提高程序性能:該做事時做事肝集,該休息時休息

存在價值

沒有RunLoop

有RunLoop

主運行循環(huán)

RunLoop 對象

  • iOS中有兩套API來訪問和使用RunLoop
    1. Foundation(NSRunLoop)
    2. Core Foundation(CFRunLoopRef)
  • NSRunLoop 和 CFRunLoopRef 都代表著 RunLoop 對象
  • NSRunLoop 是基于 CFRunLoopRef 的一層OC包裝,所以要了解 RunLoop 內(nèi)部結(jié)構(gòu)蛛壳,多研究 CFRunLoopRef 層面的 API(CoreFoundation層面)

RunLoop 與多線程

  • 每條線程都有唯一的一個與之對應(yīng)的 RunLoop 對象
  • 主線程的RunLoop 已經(jīng)自動創(chuàng)建好了,子線程的 RunLoop 需要主動創(chuàng)建
  • RunLoop 在第一次獲取時創(chuàng)建所刀,在線程結(jié)束時銷毀

獲取 RunLoop 對象

  • Foundation
[NSRunLoop currentRunLoop];  // 獲取當(dāng)前線程的 RunLoop 對象
[NSRunLoop mainRunLoop]; // 獲得主線程的 RunLoop 對象
  • Core Foundation
CFRunLoopGetCurrent(); // 獲得當(dāng)前線程的RunLoop 對象
CFRunLoopGetMain();  // 獲得主線程的 RunLoop 對象

RunLoop相關(guān)類

  • Core Foundation 中關(guān)于 RunLoop 的5個類
    1. CFRunLoopRef
    2. CFRunLoopModeRef
    3. CFRunLoopSourceRef
    4. CFRunLoopTimerRef
    5. CFRunLoopObserveRef

注:RunLoop如果沒有這些東西衙荐,會直接退出

RunLoop 應(yīng)用

  • 常駐線程
  • NSTimer
  • 自動釋放池
  • PerformSelector
  • ImageView 顯示

1. 常駐線程

應(yīng)用場景:經(jīng)常在后臺進(jìn)行耗時操作,比如:監(jiān)控聯(lián)網(wǎng)狀態(tài)浮创,掃描沙盒等忧吟,不希望線程處理完事件就銷毀,保持常駐狀態(tài)斩披。
第一種

// 開啟
- (void)run
{
// addPort: 添加端口(就是source)forMode: 設(shè)置模式
    [[NSRunLoop currentRunLoop] addPort: [NSPort port] forMode: NSDefaultRunLoopMode];
// 啟動RunLoop
    [[NSRunLoop currentRunLoop] run];

 /*
  //另外兩種啟動方式
    [NSDate distantFuture]:遙遠(yuǎn)的未來  這種寫法跟上面的run是一個意思
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    不設(shè)置模式
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
  */
}

// 退出當(dāng)前線程
[NSThread exit];

2. NSTimer (最常見 RunLoop 使用)

- (void)timer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    // 定時器只運行在NSDefaultRunLoopMode下溜族,一旦RunLoop進(jìn)入其他模式,這個定時器就不會工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

    // 定時器只運行在UITrackingRunLoopMode下垦沉,一旦RunLoop進(jìn)入其他模式煌抒,這個定時器就不會工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

    // 定時器會跑在標(biāo)記為common modes的模式下
    // 標(biāo)記為common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode兼容
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)timer2
{
    // 調(diào)用了scheduledTimer返回的定時器,已經(jīng)自動被添加到當(dāng)前runLoop中厕倍,而且是NSDefaultRunLoopMode
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
 
    // 修改模式
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

UITableView 滾動時模式由 NSDefaultRunLoopMode 進(jìn)入 UITrackingRunLoopMode寡壮,NSTimer 不再響應(yīng)。NSRunLoopCommonMode模式下兩種模式都可運行讹弯。

3. 自動釋放池

參見參考文章

main里面有個死循環(huán)就是RunLoop循環(huán)
目的:

  1. 保證程序不退出况既;
  2. 負(fù)責(zé)監(jiān)聽事件,觸摸(有沒有人摸我)组民、時鐘棒仍、網(wǎng)絡(luò)事件(回調(diào));
  3. 如果沒有時間發(fā)生臭胜,會讓程序進(jìn)入休眠狀態(tài)莫其;
  4. 五種模式,UI模式優(yōu)先級最高耸三,UI模式只能被觸摸事件觸發(fā)榜配,保證高效。
  5. 一條線程的生命只能通過任務(wù)保住

子線程里面設(shè)置定時器吕晌,可以看出子線程里面RunLoop需要自己開啟蛋褥,主線程則默認(rèn)已經(jīng)開啟。直接用while(true)并不能實現(xiàn)觸發(fā)事件效果睛驳。線程的聲明需要通過任務(wù)保住烙心,所以要將RunLoop開啟膜廊。
RunLoop是懶加載,只有第一次去拿才會創(chuàng)建淫茵。

總結(jié)一下


參考文章

https://blog.ibireme.com/2015/05/18/runloop/
深入理解RunLoop
解密-神秘的 RunLoop
(最全)RunLoop 原理+使用場景+面試總結(jié)

學(xué)習(xí)視頻

Runloop視頻 密碼:ztaf
Runloop培訓(xùn)視頻

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爪瓜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匙瘪,更是在濱河造成了極大的恐慌铆铆,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丹喻,死亡現(xiàn)場離奇詭異薄货,居然都是意外死亡,警方通過查閱死者的電腦和手機碍论,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門谅猾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鳍悠,你說我怎么就攤上這事税娜。” “怎么了藏研?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵敬矩,是天一觀的道長。 經(jīng)常有香客問我蠢挡,道長谤绳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任袒哥,我火速辦了婚禮缩筛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堡称。我一直安慰自己瞎抛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布却紧。 她就那樣靜靜地躺著桐臊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晓殊。 梳的紋絲不亂的頭發(fā)上断凶,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音巫俺,去河邊找鬼认烁。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的却嗡。 我是一名探鬼主播舶沛,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窗价!你這毒婦竟也來了如庭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤撼港,失蹤者是張志新(化名)和其女友劉穎坪它,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帝牡,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡往毡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了否灾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸣奔,死狀恐怖墨技,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挎狸,我是刑警寧澤扣汪,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站锨匆,受9級特大地震影響崭别,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恐锣,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一茅主、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧土榴,春花似錦诀姚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至矢赁,卻和暖如春糯笙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撩银。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工给涕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓稠炬,卻偏偏與公主長得像焕阿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子首启,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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

  • 1.RunLoop簡介 RunLoop實際上是一個對象暮屡,這個對象在循環(huán)中用來處理程序運行過程中出現(xiàn)的各種事件(比如...
    冰點雨閱讀 91評論 0 0
  • ======================= 前言 RunLoop 是 iOS 和 OSX 開發(fā)中非常基礎(chǔ)的一個...
    i憬銘閱讀 880評論 0 4
  • RunLoop介紹 RunLoop和線程有什么關(guān)系毅桃? 總的來說褒纲,RunLoop正如其名,loop表示某種循環(huán)钥飞,和r...
    Resoluted閱讀 444評論 0 0
  • 一莺掠、概念 簡單點說Runloop就是一個do while的運行循環(huán)。主要的作用就是保持程序的持續(xù)運行读宙。比如主線程的...
    boundlessocean閱讀 258評論 0 1
  • 我的Github地址 : Jerry4me 最近在忙著找實習(xí)的事兒, 在忙著各種知識的鞏固, 復(fù)習(xí), 趁熱打鐵把一...
    Jerry4me閱讀 896評論 0 4