ios RunLoop 用法
2019獨角獸企業重金招聘Python工程師標準>>>
A run loop for a given thread will wait until one or more of its input sources has some data or event, then fire the appropriate input handler(s) to process each input source that is "ready."?After doing so, it will then return to its loop, processing input from various sources, and "sleeping" if there is no work to do.?NSRunLoop is better than sleep?because it allows the runloop to respond to events while you wait. If you just sleep your thread your app will block even if events arrive.
其實說的簡單點兒,NSRunLoop的本質是一個消息機制的處理模式。系統級的RunLoop所示如下
關于 (BOOL) runMode:(NSString *)mode beforeDate:(NSDate *)date這個方法,具體的參數解釋如下:
1. mode指定runloop模式來處理輸入源。
2. 當date設置為[NSDate distantFuture](將來,基本不會到達的時間),所以除非處理其他輸入源結束,否則永不退出處理暫停的當前處理的流程。
一般情況下,當我們使用NSRunLoop的時候,代碼都如下所示:
do?{
? ? [[NSRunLoop?currentRunLoop]?runMode:NSDefaultRunLoopMode?beforeDate:[NSDatedistantFuture]];
}?while?(!done);
在上面的代碼中,參數done為NO的時候,當前runloop會一直接收處理其他輸入源,處理輸入源之后會再回到runloop中等待其他的輸入源;除非done為NO,否則當前流程一直再runloop中,我們用下面的一個實例來詳細的解釋如何使用NSRunLoop。
- (void) downloadImage:(NSString*)url{
?? ?
? ??_subThreed?= [NSThread?currentThread];
?? ?
? ??NSAutoreleasePool?*uploadPool = [[NSAutoreleasePool?alloc]?init];
? ??done?=?NO;
?? ?
? ??characterBuffer?= [NSMutableData?data];
?? ?
? ? [[NSURLCache?sharedURLCache]?removeAllCachedResponses];
? ??NSMutableURLRequest?*theRequest = [NSMutableURLRequest?requestWithURL:[NSURLURLWithString:url]];
? ??connection?= [[NSURLConnection?alloc]?initWithRequest:theRequest?delegate:self];
?? ? ? ?
? ??if?(connection?!=?nil) {
? ? ? ??do?{
? ? ? ? ? ? [[NSRunLoop?currentRunLoop]?runMode:NSDefaultRunLoopMode?beforeDate:[NSDatedistantFuture]];?
? ? ? ? }?while?(!done);
? ? }
?? ?
? ??imageView.image?= [UIImage?imageWithData:characterBuffer];
?? ? ? ? ? ?
? ??// Release resources used only in this thread.
? ??connection?=?nil;
? ? [uploadPool?release];
? ? uploadPool =?nil;
? ??_subThreed?=?nil;
}
上面這段代碼特別有意思的地方在于,當實例化一個connection之后,馬上執行download圖片的代理事件,同時當前進程進NSRunLoop,在這個過程中,可以響應某些輸入源,比如操作界面上的控件:點擊某個button,滑動等等事件,這些事件都可以順利執行。直到done為YES的時候,這個NSRunLoop才會結束(在具體的代碼中,我們可以在connection的didFailWithError?或者connectionDidFinishLoading代理事件中設置),結束NSRunLoop后, 代碼會繼續執行下面一行:
imageView.image?= [UIImage?imageWithData:characterBuffer];
下面是代碼在NSRunLoop中處理外部輸入源的時候callstack,我們可以清楚的看見這里比較明顯的有兩個thread,其中之一是NSRunLoop(thread 13),而另外的一個是外部輸入源的thread(thread 1)。
所以說到這里,我的理解是上面的NSRunLoop代碼和異步網絡訪問比較類似,不同點在于NSRunLoop在connection結束后會重設循環條件,這樣就結束NSRunLoop的運行,然后NSRunLoop后面的代碼就繼續執行,而異步網絡訪問則需要在connection的connectionDidFinishLoading里面執行后續的代碼。為什么這樣做呢,其實道理很簡單,為了讓整個代碼的邏輯更加清楚,如果我們沒有這樣的一個runloop的話,就不得不在子線程的結束的地方,加上imageView.image?= [UIImage?imageWithData:characterBuffer];(這個有可能是界面操作),則顯得代碼不夠緊湊,容易出錯。
轉載于:https://my.oschina.net/sunqichao/blog/178277
總結
以上是生活随笔為你收集整理的ios RunLoop 用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2. Using 'dp' instea
- 下一篇: sublime插件调用第三方程序