iOS之多線程---Runloop和多線程

1.線程與runloop的關係

原文地址1:http://blog.csdn.net/wzzvictory/article/details/9237973
原文地址2:http://blog.ibireme.com(本文還沒有寫,未完待續)

原文寫的很詳細,需要深入瞭解的請參考原文。此處我只是做一些歸納總結,日後翻閱的時候大致有一些思路。

一、線程與Runloop的關係

1.線程與runloop密切相關
1)run loop和線程是緊密相連的,可以這樣說run loop是爲了線程而生,沒有線程,它就沒有存在的必要。
2)Run loops是線程的基礎架構部分,Cocoa和CoreFundation都提供了run loop對象方便配置和管理線程的run loop。每個線程,包括程序的主線程(main thread)都有與之相應的run loop對象。

2.幾點說明
1)主線程runloop默認啓動:UIApplicationMain()函數,這個方法會爲main thread設置一個NSRunLoop對象

int main(int argc,char *argv[])
{
   @autoreleasepool {
       return UIApplicationMain(argc, argv, nil, NSStringFromClass([appDelegate class]));
   }
}

2)對其它線程來說,run loop默認是沒有啓動的,如果你需要更多的線程交互則可以手動配置和啓動,如果線程只是去執行一個長時間的已確定的任務則不需要。

3.獲取當前線程:

NSRunLoop *runloop = [NSRunLoopcurrentRunLoop];

4.runloop也負責autorelease pool的創建和釋放
典型例子:讀入大量圖像的同時改變它的尺寸。圖像文件讀入到NSData對象,並從中生成UIImage對象。改變對象尺寸後又生成 新的UIImage,此時就會產生大量autorelease的對象。

for(int i=0; i<圖像數量; i++){
    //如上操作
}

這時候,有必要在適當的地方生成、持有或者廢棄NSAutorelease對象

for(int i=0; i<圖像數量; i++){
    //如上操作
    [pool drain];  //進行一次釋放
}

總結一:

一個run loop就是一個事件處理循環,用來不停的監聽和處理輸入事件並將其分配到對應的目標上進行處理。如果僅僅是想實現這個功能,你可能會想一個簡單的while循環不就可以實現了嗎,用得着費老大勁來做個那麼複雜的機制?顯然,蘋果的架構設計師不是吃乾飯的,你想到的他們早就想過了。
1)首先,NSRunLoop是一種更加高明的消息處理模式,他就高明在對消息處理過程進行了更好的抽象和封裝,這樣才能是的你不用處理一些很瑣碎很低層次的具體消息的處理,在NSRunLoop中每一個消息就被打包在input source或者是timer source(見後文)中了。

2)important:使用run loop可以使你的線程在有工作的時候工作,沒有工作的時候休眠,這可以大大節省系統資源。

二:Runloop的深入瞭解(筆者對這部分內容使用不多,不深入講解。請參考轉載原文)

1.runloop接收輸入事件:
①輸入源:
1)當你創建輸入源,你需要將其分配給run loop中的一個或多個模式(什麼是模式,下文將會講到)。模式只會在特定事件影響監聽的源。大多數情況下,run loop運行在默認模式下,但是你也可以使其運行在自定義模式。若某一源在當前模式下不被監聽,那麼任何其生成的消息只在run loop運行在其關聯的模式下才會被傳遞。

2)傳遞異步事件,通常消息來自於其他線程或程序。輸入源傳遞異步消息給相應的處理例程,並調用runUntilDate:方法來退出(在線程裏面相關的NSRunLoop對象調用)。

②定時源:
1)需要注意的是,儘管定時器可以產生基於時間的通知,但它並不是實時機制。和輸入源一樣,定時器也和你的run loop的特定模式相關。如果定時器所在的模式當前未被run loop監視,那麼定時器將不會開始直到run loop運行在相應的模式下。類似的,如果定時器在run loop處理某一事件期間開始,定時器會一直等待直到下次run loop開始相應的處理程序。如果run loop不再運行,那定時器也將永遠不啓動。

2)定時源在預設的時間點同步方式傳遞消息,這些消息都會發生在特定時間或者重複的時間間隔。定時源則直接傳遞消息給處理例程,不會立即退出run loop。

三、什麼時候使用runloop

1)僅當在爲你的程序創建輔助線程的時候,你才需要顯式運行一個run loop

2)Run loop是程序主線程基礎設施的關鍵部分。所以,Cocoa和Carbon程序提供了代碼運行主程序的循環並自動啓動run loop。IOS程序中UIApplication的run方法(或Mac OS X中的NSApplication)作爲程序啓動步驟的一部分,它在程序正常啓動的時候就會啓動程序的主循環。

3)對於輔助線程,你需要判斷一個run loop是否是必須的。如果是必須的,那麼你要自己配置並啓動它。你不需要在任何情況下都去啓動一個線程的run loop。比如,你使用線程來處理一個預先定義的長時間運行的任務時,你應該避免啓動run loop。Run loop在你要和線程有更多的交互時才需要,比如以下情況:
使用端口或自定義輸入源來和其他線程通信
使用線程的定時器
Cocoa中使用任何performSelector…的方法
使線程週期性工作

4)如果你決定在程序中使用run loop,那麼它的配置和啓動都很簡單。和所有線程編程一樣,你需要計劃好在輔助線程退出線程的情形。讓線程自然退出往往比強制關閉它更好。

四、runloop的model:

model 主要是用來指定事件在運行循環中的優先級的,分爲:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默認,空閒狀態
UITrackingRunLoopMode:ScrollView滑動時
UIInitializationRunLoopMode:啓動時
NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合

蘋果公開提供的 Mode 有兩個:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章