RunLoop 處理事件源-- performSelector方法

一、RunLoop和線程的關(guān)系

? ? ? ?每條線程都有唯一的一個(gè)與之對(duì)應(yīng)的RunLoop對(duì)象,一個(gè)線程可以開(kāi)啟多個(gè)RunLoop,只不過(guò)都是嵌套在最大的RunLoop中证薇,其關(guān)系是保存在一個(gè)全局的 Dictionary 里桥氏。

二、線程中RunLoop的生命周期

創(chuàng)建:

? ? ?1瓣蛀、主線程:run loop默認(rèn)是啟動(dòng)的陆蟆,用于接收各種輸入sources

? ? ? 2、子線程:線程剛創(chuàng)建時(shí)并沒(méi)有 RunLoop惋增,如果你不主動(dòng)獲取叠殷,那它一直都不會(huì)有。

? ? ?在當(dāng)前子線程中調(diào)用[NSRunLoop currentRunLoop]的時(shí)候诈皿,如果有就獲取林束,沒(méi)有就創(chuàng)建

啟動(dòng):

? ? ?1、主線程:默認(rèn)是啟動(dòng)的

? ? ?2稽亏、子線程:要手動(dòng)添加

獲群啊:

? ? ?1、主線程:全局獲取其RunLoop;[NSRunLoop mainRunLoop]或者 CFRunLoopGetMain();

? ? ? 2截歉、子線程:只能在線程的內(nèi)部獲取其RunLoop;[NSRunLoop currentRunLoop]或者CFRunLoopGetCurrent();

銷毀:

? ? 1胖腾、主線程:app結(jié)束時(shí)

? ? 2、子線程:子線程結(jié)束

三、在當(dāng)前線程的Run Loop下執(zhí)行指定的 @selector 方法

? ? ?當(dāng)調(diào)用 NSObject的performSelector:onThread:時(shí)胸嘁,實(shí)際上其內(nèi)部會(huì)創(chuàng)建一個(gè) Timer 并添加到當(dāng)前線程的 RunLoop 中:

打印一下看看:

其實(shí)是加在runloop中

看以下的代碼:

- (void)viewDidLoad {

? ? ?[super viewDidLoad];

? ? ?NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(nslogHi) object:nil];

? ? ?[thread start];

? ? ?[self performSelector:@selector(nslogHello) onThread:thread withObject:nil waitUntilDone:NO];

? ? NSLog(@"_end");

}

- (void)nslogHi {

? ? ? NSLog(@"hi....");

}

- (void)nslogHello {

? ? ? NSLog(@"hello.....");

}

最會(huì)輸出:

? ? ?2015-09-28 14:09:15.650 PCRunLoopThread[74414:5556013] hi....

? ? ?2015-09-28 14:09:15.650 PCRunLoopThread[74414:5555961] _end

結(jié)論:

? ? ? 1瓶摆、線程在執(zhí)行后會(huì)退出當(dāng)前的RunLoop,也就是RunLoop會(huì)在一個(gè)線程結(jié)束時(shí)一同銷毀性宏。

? ? ? 2群井、如果當(dāng)前線程沒(méi)有RunLoop的話,performSelector:onThread的方法也就失效毫胜。

==================================================

那么我們要想要把hello.....打印出來(lái)J樾薄!要怎么辦呢酵使?

就線程一直運(yùn)行或者暫時(shí)阻塞一下線程:

1荐吉、向創(chuàng)建的RunLoop添加NSPort(Sources),讓Mode不為空口渔,RunLoop能進(jìn)入循環(huán)不會(huì)退出

? ? ? [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

? ? ? [[NSRunLoop currentRunLoop] run];

見(jiàn)代碼:

- (void)nslogHi {

? ? ? [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

? ? ? [[NSRunLoop currentRunLoop] run];

? ? ?NSLog(@"hi....");

}

使用run啟動(dòng)線程样屠,是不會(huì)退出,所以也就打印不出hi....

2缺脉、讓RunLoop一直嘗試運(yùn)行痪欲,判斷Mode是否為空,不是為空就進(jìn)入RunLoop循環(huán)

? ? ? ?[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]

見(jiàn)代碼:

- (void)nslogHi {

? ? ?while (!_isNewThreadAborted) {

? ? ? ? ? ? ?BOOL ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode

? ? ? ? ? ? beforeDate:[NSDate distantFuture]];

? ? ? ? }

? ? ? ? NSLog(@"hi....");

}

具體的demo

網(wǎng)上找了些資料攻礼,貼一下的三種手動(dòng)啟動(dòng)runloop的方式:

讓一個(gè)子線程不進(jìn)入消亡狀態(tài)业踢,等待其他線程發(fā)來(lái)消息,處理其他事件,其實(shí)就是讓線程跑一個(gè)runLoop

1礁扮、- (void)run;

運(yùn)行 NSRunLoop知举,運(yùn)行模式為默認(rèn)的NSDefaultRunLoopMode模式,沒(méi)有超時(shí)限制太伊。因?yàn)闊o(wú)條件運(yùn)行

不建議使用雇锡,因?yàn)檫@個(gè)接口會(huì)導(dǎo)致Run Loop永久性的運(yùn)行在NSDefaultRunLoopMode模式,即使使用CFRunLoopStop(runloopRef);也無(wú)法停止Run Loop的運(yùn)行僚焦,那么這個(gè)子線程就無(wú)法停止遮糖,只能永久運(yùn)行下去。

示例:

[[NSRunLoop currentRunLoop] run];

2叠赐、[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];

運(yùn)行 NSRunLoop: 參數(shù)為運(yùn)時(shí)間期限,運(yùn)行模式為默認(rèn)的NSDefaultRunLoopMode模式屡江,自己設(shè)置的Run Loop運(yùn)行時(shí)間芭概,超時(shí)就退出

示例:

while (!Done)

{

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate

dateWithTimeIntervalSinceNow:10]];

NSLog(@"exiting runloop.........:");

}

3、- (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate;

mode: ? 指定runloop模式來(lái)處理輸入源

limitDate:設(shè)置為NSDate distantFuture惩嘉,所以除非處理其他輸入源結(jié)束罢洲,否則永不退出處理暫停的當(dāng)前處理的流程

return: ? 返回值為YES表示是處理事件后返回的,NO表示是超時(shí)或者停止運(yùn)行導(dǎo)致返回的

這個(gè)接口在非Timer事件觸發(fā)、顯式的用CFRunLoopStop停止Run Loop惹苗、到達(dá)limitDate后會(huì)退出返回殿较。

如果僅是Timer事件觸發(fā)并不會(huì)讓Run Loop退出返回;

如果是PerfromSelector***事件或者其他Input Source事件觸發(fā)處理后桩蓉,Run Loop會(huì)退出返回YES淋纲。

示例:

while (!Done)

{

BOOL ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode

beforeDate:[NSDate distantFuture]];

NSLog(@"exiting runloop.........: %d", ret);

}

當(dāng)判斷條件為YES時(shí),當(dāng)前runloop會(huì)一直接收處理其他輸入源院究,當(dāng)前流程不繼續(xù)往下執(zhí)行洽瞬。

當(dāng)判斷出為A為NO,當(dāng)前流程繼續(xù)往下執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末业汰,一起剝皮案震驚了整個(gè)濱河市伙窃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌样漆,老刑警劉巖为障,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異放祟,居然都是意外死亡鳍怨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)舞竿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)京景,“玉大人,你說(shuō)我怎么就攤上這事骗奖∪丰悖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵执桌,是天一觀的道長(zhǎng)鄙皇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)仰挣,這世上最難降的妖魔是什么伴逸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮膘壶,結(jié)果婚禮上错蝴,老公的妹妹穿的比我還像新娘。我一直安慰自己颓芭,他們只是感情好顷锰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著亡问,像睡著了一般官紫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天束世,我揣著相機(jī)與錄音酝陈,去河邊找鬼。 笑死毁涉,一個(gè)胖子當(dāng)著我的面吹牛沉帮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播薪丁,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼遇西,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了严嗜?” 一聲冷哼從身側(cè)響起粱檀,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漫玄,沒(méi)想到半個(gè)月后茄蚯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡睦优,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年渗常,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汗盘。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡皱碘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隐孽,到底是詐尸還是另有隱情癌椿,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布菱阵,位于F島的核電站踢俄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晴及。R本人自食惡果不足惜都办,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虑稼。 院中可真熱鬧琳钉,春花似錦、人聲如沸蛛倦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胰蝠。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茸塞,已是汗流浹背躲庄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钾虐,地道東北人噪窘。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像效扫,于是被迫代替她去往敵國(guó)和親倔监。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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

  • 什么是Run Loops RunLoops是與線程相關(guān)聯(lián)的基礎(chǔ)部分菌仁,一個(gè)Run Loop就是事件處理循環(huán)浩习,他是用來(lái)...
    傻傻小蘿卜閱讀 967評(píng)論 0 5
  • 首先看一段AF2.x經(jīng)典代碼: 首先我們要明確一個(gè)概念摹迷,線程一般都是一次執(zhí)行完任務(wù)疟赊,就銷毀了。 而添加了runlo...
    涂耀輝閱讀 22,517評(píng)論 42 293
  • 什么情況下使用runloop峡碉? runloop好比就是跑圈近哟,就是一個(gè)線程一直在做某一件事情。 一般主線程會(huì)自動(dòng)運(yùn)行...
    進(jìn)擊的小杰閱讀 4,416評(píng)論 4 7
  • 一鲫寄、什么是runloop 字面意思是“消息循環(huán)吉执、運(yùn)行循環(huán)”。它不是線程塔拳,但它和線程息息相關(guān)鼠证。一般來(lái)講,一個(gè)線程一次...
    WeiHing閱讀 8,146評(píng)論 11 111
  • Run loop 剖析:Runloop 接收的輸入事件來(lái)自兩種不同的源:輸入源(intput source)和定時(shí)...
    Mitchell閱讀 12,437評(píng)論 17 111