亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

NSRunLoop概述和原理[轉(zhuǎn)]

系統(tǒng) 2644 0
1.什么是NSRunLoop?
我們會(huì)經(jīng)??吹竭@樣的代碼:

    - (IBAction)start:(id)sender
{
pageStillLoading = YES;
[NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
[progress setHidden:NO];
while (pageStillLoading) {
[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[progress setHidden:YES];
} 

  


這段代碼很神奇的,因?yàn)樗麜?huì)“暫?!贝a運(yùn)行,而且程序運(yùn)行不會(huì)因?yàn)檫@里有一個(gè)while循環(huán)而受到影響。在[progress setHidden:NO]執(zhí)行之后,整個(gè)函數(shù)想暫停了一樣停在循環(huán)里面,等loadPageInBackground里面的操作都完成了以后才讓[progress setHidden:YES]運(yùn)行。這樣做就顯得簡介,而且邏輯很清晰。如果你不這樣做,你就需要在loadPageInBackground里面表示load完成的地方調(diào)用[progress setHidden:YES],顯得代碼不緊湊而且容易出錯(cuò)。
那么具體什么是NSRunLoop呢?其實(shí)NSRunLoop的本質(zhì)是一個(gè)消息機(jī)制的處理模式。如果你對vc++編程有一定了解,在windows中,有一系列很重要的函數(shù)SendMessage,PostMessage,GetMessage,這些都是有關(guān)消息傳遞處理的API。但是在你進(jìn)入到Cocoa的編程世界里面,我不知道你是不是走的太快太匆忙而忽視了這個(gè)很重要的問題,Cocoa里面就沒有提及到任何關(guān)于消息處理的API,開發(fā)者從來也沒有自己去關(guān)心過消息的傳遞過程,好像一切都是那么自然,像大自然一樣自然?在Cocoa里面你再也不用去自己定義WM_COMMAD_XXX這樣的宏來標(biāo)識某個(gè)消息,也不用在switch-case里面去對特定的消息做特別的處理。難道是Cocoa里面就沒有了消息機(jī)制?答案是否定的,只是Apple在設(shè)計(jì)消息處理的時(shí)候采用了一個(gè)更加高明的模式,那就是RunLoop。

2. NSRunLoop工作原理
接下來看一下NSRunLoop具體的工作原理,首先是官方文檔提供的說法,看圖:

NSRunLoop概述和原理[轉(zhuǎn)]

通過所有的“消息”都被添加到了NSRunLoop中去,而在這里這些消息并分為“input source”和“Timer source” 并在循環(huán)中檢查是不是有事件需要發(fā)生,如果需要那么就調(diào)用相應(yīng)的函數(shù)處理。為了更清晰的解釋,我們來對比VC++和iOS消息處理過程。

VC++中在一切初始化都完成之后程序就開始這樣一個(gè)循環(huán)了(代碼是從戶sir mfc程序設(shè)計(jì)課程的slides中截取):

    

 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR  lpCmdLine,int nCmdShow){
...
while (GetMessage(&msg, NULL, 0, 0)){
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} 

  


可以看到在GetMessage之后就去分發(fā)處理消息了,而iOS中main函數(shù)中只是調(diào)用了UIApplicationMain,那么我們可以介意猜出UIApplicationMain在初始化完成之后就會(huì)進(jìn)入這樣一個(gè)情形:

    int UIApplicationMain(...){
...
while(running){
[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
...
} 

  


所以在UIApplicationMain中也是同樣在不斷處理runloop才是的程序沒有退出。剛才的我說了NSRunLoop是一種更加高明的消息處理模式,他就高明在對消息處理過程進(jìn)行了更好的抽象和封裝,這樣才能是的你不用處理一些很瑣碎很低層次的具體消息的處理,在NSRunLoop中每一個(gè)消息就被打包在input source或者是timer source中了,當(dāng)需要處理的時(shí)候就直接調(diào)用其中包含的相應(yīng)對象的處理函數(shù)了。所以對外部的開發(fā)人員來講,你感受到的就是,把source/timer加入到runloop中,然后在適當(dāng)?shù)臅r(shí)候類似于[receiver action]這樣的事情發(fā)生了。甚至很多時(shí)候,你都沒有感受到整個(gè)過程前半部分,你只是感覺到了你的某個(gè)對象的某個(gè)函數(shù)調(diào)用了。比如在UIView被觸摸時(shí)會(huì)用touchesBegan/touchesMoved等等函數(shù)被調(diào)用,也許你會(huì)想,“該死的,我都不知道在那里被告知有觸摸消息,這些處理函數(shù)就被調(diào)用了?。俊彼?,消息是有的,只是runloop已經(jīng)幫你做了!為了證明我的觀點(diǎn),我截取了一張debug touchesBegan的call stack,有圖有真相:


NSRunLoop概述和原理[轉(zhuǎn)]

NSRunLoop概述和原理[轉(zhuǎn)]


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦?。。?/p>

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91久久国产精品视频 | 极品福利在线 | 日本爱爱网 | 国产免费一级高清淫曰本片 | 国产精品二区高清在线 | 不卡一区在线观看 | 久热精品视频在线观看 | 国产精品一区二 | 一级毛片无毒不卡直接观看 | 天天摸日日摸 | 91精品国产三级在线观看 | 国产精品国色综合久久 | 天天干天天天天 | 国产欧美综合在线一区二区三区 | 国产高清a毛片在线看 | 精品视频入口 | 免费a级毛片出奶水 | a毛片成人免费全部播放 | 欧美高清精品 | 欧美一级毛片视频 | 99精品久久久久久 | 377p欧洲最大胆艺术 | 国产一区二区亚洲精品 | 国产成人精品一区 | 久久亚洲精品一区成人 | 国产精品国产欧美综合一区 | 中文字幕在线观看一区二区三区 | 夜夜艹天天干 | 一级毛片成人免费看a | 精品久久中文网址 | 男人的影院 | 免费a级网站 | 久久9999国产精品免费 | 国产精品视频2021 | 久久成人小视频 | 欧美成人xxxx | 狠狠色婷婷丁香六月 | 精品成人免费一区二区在线播放 | 国产精品午夜高清在线观看 | 九九99久久 | 久久成年人|