運(yùn)行循環(huán)是什么?從介紹到演示

今天整理一下運(yùn)行循環(huán)來幫朋友們了解一下什么是運(yùn)行循環(huán),也叫消息循環(huán),建議大家稱之為運(yùn)行循環(huán)(Runloop).


===

關(guān)于多線程的運(yùn)行循環(huán)(消息循環(huán))

1. 什么是運(yùn)行循環(huán)

(1)Runloop就是運(yùn)行循環(huán),每個線程內(nèi)部都有一個運(yùn)行循環(huán).

(2)只有主線程的運(yùn)行循環(huán)默認(rèn)是開啟的,子線程的運(yùn)行循環(huán).

2. 運(yùn)行循環(huán)的作用

(1)保證程序不退出,iOS的應(yīng)用程序啟動之后,之所以不會退出,就是因為有Runloop(運(yùn)行循環(huán)).運(yùn)行循環(huán)是一個死循環(huán),只有滿足一定條件才會結(jié)束循環(huán).

(2)負(fù)責(zé)處理輸入事件

(3)如果沒有事件發(fā)生,會讓程序進(jìn)入休眠狀態(tài).

3.輸入事件

Runloop接收的事件來自兩種不同的來源:輸入源 和 定時源.

(1)輸入源(Input sources)輸入源傳遞異步事件,通常消息來自于其他線程或程序坷剧。

(2)定時源(Timer sounces)定時源則傳遞同步事件陵叽,發(fā)生在特定時間或者重復(fù)的時間間隔独令。兩種源都使用程序的某一特定的處理例程來處理到達(dá)的事件。

(3)下圖展示了運(yùn)行循環(huán)的概念結(jié)構(gòu)以及事件來源的種類:
輸入源能夠通過runUntilDate 方法使線程退出;定時源不能使線程退出.

runloop.png

4.運(yùn)行循環(huán)的模式

運(yùn)行循環(huán)模式是輸入源和定時源的一個集合,這個集合會被監(jiān)聽.

每次啟動運(yùn)行循環(huán)稠曼,可以指定一個特殊的模式,在運(yùn)行循環(huán)執(zhí)行期間客年,只有跟特定的模式相關(guān)聯(lián)的事件源才會被監(jiān)聽以及允許傳遞它們的事件霞幅。跟其它模式相關(guān)聯(lián)的事件源將不會被監(jiān)聽。因此量瓜,可以通過運(yùn)行循環(huán)來過濾掉一些不期望的事件

下圖是系統(tǒng)定義的幾種運(yùn)行循環(huán)模式:

Mode Name Description
Default NSDefaultRunLoopMode(Cocoa)kCFRunLoopDefaultMode (Core Foundation) The default mode is the one used for most operations. Most of the time, you should use this mode to start your run loop and configure your input sources.
Connection NSConnectionReplyMode(Cocoa) Cocoa uses this mode in conjunction with NSConnection objects to monitor replies. You should rarely need to use this mode yourself
Modal NSModalPanelRunLoopMode(Cocoa) Cocoa uses this mode to identify events intended for modal panels.
Event tracking NSEventTrackingRunLoopMode(Cocoa) Cocoa uses this mode to restrict incoming events during mouse-dragging loops and other sorts of user interface tracking loops.
Common modes NSRunLoopCommonModes(Cocoa)kCFRunLoopCommonModes (Core Foundation) This is a configurable group of commonly used modes. Associating an input source with this mode also associates it with each of the modes in the group. For Cocoa applications, this set includes the default, modal, and event tracking modes by default. Core Foundation includes just the default mode initially. You can add custom modes to the set using theCFRunLoopAddCommonMode function.

大致的意思是指:

(1)Default: default模式可以用于大多數(shù)操作司恳。在大多數(shù)時間,應(yīng)該使用這種模式來啟動和設(shè)置輸入源绍傲。

(2)Connection: Cocoa使用這種模式聯(lián)合NSConnection對象來監(jiān)聽響應(yīng)扔傅。我們很少會自己用到這種模式

(3)Modal: Cocoa使用這種模式來識別為模態(tài)面板準(zhǔn)備的事件。

(4)Event tracking: Cocoa使用這種模式來約束鼠標(biāo)拖拽或其它用戶界面追蹤循環(huán)的事件烫饼。

(5)Common modes: 這是一個通用的模式組猎塞,使用這種模式關(guān)聯(lián)輸入源,同樣會關(guān)聯(lián)這個模式組里面的每一種模式枫弟。對于Cocoa應(yīng)用來說邢享,這個集合包含了 default、modal以及event tracking模式淡诗。
Core Foundation初始狀態(tài)下只包含 default 模式骇塘,但是可以
通過 CFRunLoopAddCommonMode函數(shù)來添加自定義模式。

5.通過定時器演示運(yùn)行循環(huán)的模式

注意:定時器執(zhí)行的方法中不宜執(zhí)行太耗時的操作,否則會降低用戶體驗.

  • 第一步:創(chuàng)建定時器
    在viewDidLoad方法中:
//1,創(chuàng)建定時器
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:
self selector:@selector(demo) userInfo:nil repeats:YES]; 
//demo方法
- (void)demo {
        NSLog(@"hello");
}
  • 第二步:將定時器添加到當(dāng)前線程的運(yùn)行循環(huán)
//將定時器添加到當(dāng)前線程的運(yùn)行循環(huán)
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

===

注意:這里的模式對應(yīng)的是輸入事件(定時器timer)的模式.

  • 第三步:運(yùn)行程序,執(zhí)行結(jié)果如下:
屏幕快照 2016-03-12 下午9.54.24.png
當(dāng)程序運(yùn)行起來之后,打印輸出會按照定時器,每秒輸出一次.但是,如果拖動界面的控件,打印輸出就會停止(即不再打印輸出).
思考:為什么?
  • 第四步: 打印當(dāng)前運(yùn)行循環(huán)的模式

demo方法中:

NSLog(@"---%@", [NSRunLoop currentRunLoop].currentMode);

執(zhí)行程序:

屏幕快照 2016-03-12 下午9.58.52.png

注意:[NSRunLoop currentRunLoop].currentMode 中的模式對應(yīng)的是運(yùn)行循環(huán)的模式韩容。

結(jié)論:
運(yùn)行循環(huán)是在一個指定的模式下運(yùn)行的(默認(rèn)是NSDefaultRunLoopMode)款违,設(shè)置的輸入事件也需要指定一個模式,運(yùn)行循環(huán)的模式必須和輸入事件的模式相匹配才會執(zhí)行群凶。
一開始插爹,輸入事件模式是NSDefaultRunLoopMode,運(yùn)行循環(huán)默認(rèn)也是NSDefaultRunLoopMode螟深,所以可以正常輸出結(jié)果矮燎。
拖動控件,之所以不會打印輸出局义,就是因為運(yùn)行循環(huán)的模式發(fā)生了改變气嫁,變成了 UITrackingRunLoopMode当窗,這個時候二者模式不匹配,所以不能正常輸出寸宵。

總結(jié):

(1)運(yùn)行循環(huán)是在一個指定的模式下運(yùn)行的崖面,輸入事件也有對應(yīng)的模式,只有當(dāng)二者的模式相匹配梯影,對應(yīng)的方法才會執(zhí)行巫员。

(2)運(yùn)行循環(huán)模式:
1> 運(yùn)行循環(huán)啟動后,默認(rèn)模式為 NSRunLoopDefaultMode
2> 如果滾動scrollView甲棍,運(yùn)行循環(huán)模式為 UITrackingRunLoopMode简识。

子線程的運(yùn)行循環(huán)

主線程的運(yùn)行循環(huán)默認(rèn)是開啟的,子線程的運(yùn)行循環(huán)默認(rèn)是不開啟的救军。
//第一步: 創(chuàng)建子線程
viewDidLoad方法中: 
    // 創(chuàng)建子線程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
    [thread start];
//第二步: 往子線程的運(yùn)行循環(huán)添加輸入源
// 往子線程的運(yùn)行循環(huán)上添加輸入源
    [self performSelector:@selector(demo1) onThread:thread withObject:
nil waitUntilDone:NO];
// 執(zhí)行在子線程的方法
- (void)demo {
     NSLog(@"I'm running");
}
// 執(zhí)行在子線程的運(yùn)行循環(huán)中的方法
- (void)demo1 {
-   NSLog(@"I'm running on runloop");
}
第三步: 開啟子線程的運(yùn)行循環(huán)
- (void)demo {
    NSLog(@"I'm running");
    // 這些數(shù)入源能夠防止運(yùn)行循環(huán)退出, 即 只要有數(shù)入源, run 方法啟動的運(yùn)行循環(huán)就不會退出
    // Those sources could therefore prevent the run loop from exiting.
[[NSRunLoop currentRunLoop] run];
NSLog(@"end");
}
然后執(zhí)行程序得到以下結(jié)果:

屏幕快照 2016-03-12 下午10.05.45.png

由輸出結(jié)果可知: 沒有打印 end财异,即只要有輸入源倘零,使用run方法啟動的運(yùn)行循環(huán)不會退出唱遭。

第五步: 通過 runUntilDate來啟動運(yùn)行循環(huán)

// 2秒鐘之后消息循環(huán)結(jié)束

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];

這樣的話,2秒鐘之后呈驶,子線程的運(yùn)行循環(huán)就會退出拷泽。

希望能幫到大家!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市袖瞻,隨后出現(xiàn)的幾起案子司致,更是在濱河造成了極大的恐慌,老刑警劉巖聋迎,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脂矫,死亡現(xiàn)場離奇詭異,居然都是意外死亡霉晕,警方通過查閱死者的電腦和手機(jī)庭再,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牺堰,“玉大人拄轻,你說我怎么就攤上這事∥昂” “怎么了恨搓?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我斧抱,道長常拓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任辉浦,我火速辦了婚禮墩邀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盏浙。我一直安慰自己眉睹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布废膘。 她就那樣靜靜地躺著竹海,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丐黄。 梳的紋絲不亂的頭發(fā)上斋配,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機(jī)與錄音灌闺,去河邊找鬼艰争。 笑死,一個胖子當(dāng)著我的面吹牛桂对,可吹牛的內(nèi)容都是我干的甩卓。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蕉斜,長吁一口氣:“原來是場噩夢啊……” “哼逾柿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宅此,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤机错,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后父腕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弱匪,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年璧亮,在試婚紗的時候發(fā)現(xiàn)自己被綠了萧诫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡杜顺,死狀恐怖财搁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躬络,我是刑警寧澤尖奔,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響提茁,放射性物質(zhì)發(fā)生泄漏淹禾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一茴扁、第九天 我趴在偏房一處隱蔽的房頂上張望铃岔。 院中可真熱鬧,春花似錦峭火、人聲如沸毁习。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纺且。三九已至,卻和暖如春稍浆,著一層夾襖步出監(jiān)牢的瞬間载碌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工衅枫, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嫁艇,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓弦撩,卻偏偏與公主長得像步咪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子孤钦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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