iOS運行迴路(RunLoop)總結

來源:互聯網
上載者:User

首先看兩個runloop的樣本,來源:http://paste.lisp.org/display/86524

第一個:

 

  1. #include <CoreFoundation/CoreFoundation.h>  
  2.   
  3. static void  
  4. _perform(void *info __unused)  
  5. {  
  6.     printf("hello\n");  
  7. }  
  8.   
  9. static void  
  10. _timer(CFRunLoopTimerRef timer __unused, void *info)  
  11. {  
  12.     CFRunLoopSourceSignal(info);  
  13. }  
  14.   
  15. int  
  16. main()  
  17. {  
  18.     CFRunLoopSourceRef source;  
  19.     CFRunLoopSourceContext source_context;  
  20.     CFRunLoopTimerRef timer;  
  21.     CFRunLoopTimerContext timer_context;  
  22.   
  23.     bzero(&source_context, sizeof(source_context));  
  24.     source_context.perform = _perform;  
  25.     source = CFRunLoopSourceCreate(NULL, 0, &source_context);  
  26.     CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);  
  27.   
  28.     bzero(&timer_context, sizeof(timer_context));  
  29.     timer_context.info = source;  
  30.     timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 1, 0, 0, _timer, &timer_context);  
  31.     CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);  
  32.   
  33.     CFRunLoopRun();  
  34.   
  35.     return 0;  
  36. }  

 

第二個:

 

  1. #include <dispatch/dispatch.h>  
  2. #include <stdio.h>  
  3.   
  4. int  
  5. main()  
  6. {  
  7.     dispatch_source_t source, timer;  
  8.   
  9.     source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));  
  10.     dispatch_source_set_event_handler(source, ^{  
  11.         printf("hello\n");  
  12.     });  
  13.     dispatch_resume(source);  
  14.   
  15.     timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));  
  16.     dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 0);  
  17.     dispatch_source_set_event_handler(timer, ^{  
  18.         dispatch_source_merge_data(source, 1);  
  19.     });  
  20.     dispatch_resume(timer);  
  21.   
  22.     dispatch_main();  
  23. }  

 

功能是向main線程中加入兩個input source,一個是timer,一個是自訂input source,然後這個timer中觸發自訂source,於是調用其回調方法。 在這兒timer觸發source來調用回調方法,顯得有點多此一舉。但是在多線程開發當中,這就很有用了,我們可以把這個自訂的source加入到子線程的runloop中,然後在主線程中觸發source,這樣在子線程中就可以調用回調方法了。  這樣做的好久是什麼呀? 節約用電,因為runloop一般情況下是休眠的,只有事件觸發的時候才開始工作。 這與windows下的waitforsingleobject有點類似, 與多線程中的訊號量,事件也有些雷同。

 

上面說到的input source(輸入源例)到底是什麼呢?輸入源範例可能包括使用者輸入裝置(如點擊button)、網路連結(socket收到資料)、定期或時間延遲事件(NSTimer),還有非同步回調(NSURLConnection的非同步請求)。然後我們對其進行了分類,有三類可以被runloop監控,分別是sources、timers、observers。

在蘋果文檔中對runloop有詳細介紹,下面參考中有中文版。那文檔中的代碼關於NSPort的部份在iOS上是不行的,不過可以用其CF方法實現,在我的demo中有展示。

 

每一個線程都有自己的runloop, 主線程是預設開啟的,建立的子線程要手動開啟,因為NSApplication 只啟動main applicaiton thread。

沒有source的runloop會自動結束。

事件由NSRunLoop 類處理。

RunLoop監視作業系統的輸入源,如果沒有事件數目據, 不消耗任何CPU 資源。

如果有事件數目據,run loop 就發送訊息,通知各個對象。

用 currentRunLoop 獲得 runloop的 reference

給 runloop 發送run 訊息啟動它。

 

 

文檔中介紹下面四種情況是使用runloop的場合:

 1.使用連接埠或自訂輸入源和其他線程通訊

 2.子線程中使用了定時器

 3.cocoa中使用任何performSelector到了線程中運行方法

 4.使線程履行週期性任務,(我把這個理解與2相同)

如果我們在子線程中用了NSURLConnection非同步請求,那也需要用到runloop,不然線程退出了,相應的delegate方法就不能觸發。

解決的方法參看:

http://www.cocoabyss.com/foundation/nsurlconnection-synchronous-asynchronous/

http://www.wim.me/nsurlconnection-in-its-own-thread/

 

具體參看demo.

 

 

參考:

http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

http://www.wim.me/nsurlconnection-in-its-own-thread/

http://xubenyang.me/384

http://iphonedevelopmentbits.com/event-driven-multitasking-runloopssymbian-ios

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.