iOS中的多線程

來源:互聯網
上載者:User

標籤:

 

iOS中的多線程    

首先來瞭解什麼是多線程,進程和線程的區別.

進程:

    進行中中的程式被稱為進程,負責程式啟動並執行記憶體配置;

    每一個進程都有自己獨立的虛擬記憶體空間.

線程:(主線程最大佔1M的棧區空間,每條子線程最大佔512K的棧區空間)

    線程是進程中一個獨立的執行路徑(控制單元);

    一個進程中至少包含一條線程,即主線程;

    可以將耗時的執行路徑(如網路請求)放在其他線程中執行;

    線程不能被殺掉,但是可以暫停/休眠一條線程.

建立線程的目的:

    開啟一條新的執行路徑,運行指定的代碼,與主線程中的代碼實現同時運行.

多任務調度系統:

    每個應用程式由作業系統分配的短暫的時間片(Timeslice)輪流使用CPU,由於CPU對每個時間片的處理速度非常快,因此,使用者看來這些任務好像是同時執行的.    

並發:

    指兩個或多個任務在同一時間間隔內發生,但是,在任意一個時間點上,CPU只會處理一個任務.

多線程的優勢:

    1> 充分發揮多核處理器優勢,將不同線程任務分配給不同的處理器,真正進入"並行運算"狀態;

    2> 將耗時的任務分配到其他線程執行,由主線程負責統一更新介面會使應用程式更加流暢,使用者體驗更好;

    3> 當硬體處理器的數量增加,程式會運行更快,而程式無需做任何調整.

弊端:

    建立線程會消耗記憶體空間和CPU時間,線程太多會降低系統的運行效能.

iOS的三種多線程技術特點:

1.NSThread:

    1> 使用NSThread對象建立一個線程非常方便;

    2> 但是!要使用NSThread管理多個線程非常困難,不推薦使用;

    3> 技巧!使用[NSThread currentThread]跟蹤任務所線上程,適用於這三種技術.

2.NSOperation/NSOperationQueue:

    1> 是使用GCD實現的一套Objective-C的API;

    2> 是物件導向的多線程技術;

    3> 提供了一些在GCD中不容易實現的特性,如:限制最大並發數量,操作之間的依賴關係.

3.GCD---Grand Central Dispatch:

    1> 是基於C語言的底層API;

    2> 用Block定義任務,使用起來非常靈活便捷;

    3> 提供了更多的控制能力以及操作隊列中所不能使用的底層函數.

iOS的開發人員需要瞭解三種多線程技術的基本使用,因為在實際開發中會根據實際情況選擇不同的多線程技術.

GCD基本思想

    GCD的基本思想就是將操作S放在隊列S中去執行.

    1> 操作使用Blocks定義;

    2> 隊列負責調度任務執行所在的線程以及具體的執行時間;

    3> 隊列的特點是先進先出(FIFO)的,新添加至隊列的操作都會排在隊尾.

提示:

    GCD的函數都是以dispatch(指派/調度)開頭的.

隊列:

    dispatch_queue_t

    串列隊列: 隊列中的任務只會順序執行;

    並行隊列: 隊列中的任務通常會並發執行.

操作:

    dispatch_async 非同步作業,會並發執行,無法確定任務的執行順序;

    dispatch_sync 同步操作,會依次順序執行,能夠決定任務的執行順序.

隊列不是線程,也不表示對應的CPU.隊列就是負責調度的.多線程技術的目的,就是為了在一個CPU上實現快速切換!

在串列隊列中:

    同步操作不會建立線程,操作順序執行(沒用!);

    非同步作業會建立線程,操作順序執行(非常有用!) (應用情境:既不影響主線程,又需要順序執行的操作).

在並行隊列中:

    同步操作不會建立線程,操作順序執行;

    非同步作業會建立多個線程,操作無序執行(有用,容易出錯),隊列前如果有其他任務,會等待前面的任務完成之後再執行.應用情境:既不影響主線程,又不需要順序執行的操作.

全域隊列:

    全域隊列是系統的,直接拿過來(GET)用就可以,與並行對立類似,但調試時,無法確認操作所在隊列.

主隊列:

    每一個應用程式都對應唯一一個主隊列,直接GET即可,在多線程開發中,使用主隊列更新UI;

注意:

    主隊列中的操作都應該在主線程上順序執行,不存在非同步概念.

    如果把主線程中的操作看作是一個大的Block,那麼除非主線程被使用者殺掉,否則永遠不會結束.所以主隊列中添加的同步操作永遠不會被執行,會死結.

不同隊列中嵌套同步操作dispatch_sync的結果:?
12345678 // 全域隊列,都在主線程上執行,不會死結dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 並行隊列,都在主線程上執行,不會死結dispatch_queue_t q = dispatch_queue_create("m.baidu.com", DISPATCH_QUEUE_CONCURRENT);// 串列隊列,會死結,但是會執行嵌套同步操作之前的代碼dispatch_queue_t q = dispatch_queue_create("m.baidu.com", DISPATCH_QUEUE_SERIAL);// 直接死結dispatch_queue_t q = dispatch_get_main_queue();

 

同步操作dispatch_sync的應用情境:

    阻塞並行隊列的執行,要求某一操作執行後再進行後續操作,如使用者登入.

    確保塊代碼之外的局部變數確實被修改.

    [NSThread sleepForTimeInterval:2.0f] 通常在多線程調試中用於類比耗時操作,在發布的應用程式中,不要使用此方法!

    無論什麼隊列和什麼任務,線程的建立和回收都不需要程式員參與.線程的建立回收工作是由隊列負責的.

GCD優點:

    1> 通過GCD,開發人員不用再直接跟線程打交道,只需要向隊列中添加代碼塊即可.    

    2> GCD在後端管理著一個線程池,GCD不僅決定著代碼塊將在哪個線程被執行,它還根據可用的系統資源對這些線程進行管理,從而讓開發人員從線程管理的工作中解放出來;通過集中的管理線程,緩解大量線程被建立的問題.

    3> 使用GCD,開發人員可以將工作考慮為一個隊列,而不是一堆線程,這種並行的抽象模型更容易掌握和使用.     

GCD隊列:

    蘋果官方給出的GCD隊列:

            

    從中可以看出: GCD公開有5個不同的隊列:運行在主線程中的主隊列,3個不同優先順序的後台隊列以及一個優先順序更低的後台隊列(用於I/O).

    自訂隊列:串列和並行隊列.自訂隊列非常強大,建議在開發中使用.

    在自訂隊列中被調度的所有Block最終都將被放入到系統的全域隊列中和線程池中.

提示:

    不建議使用不同優先順序的隊列,因為如果設計不當,可能會出現優先順序反轉,即低優先順序的操作阻塞高優先順序的操作.

NSOperation&NSOperationQueue簡介:

    1> NSOperationQueue(操作隊列)是由GCD提供的隊列模型的Cocoa抽象,是一套Objective-C的API;

    2> GCD提供了更加底層的控制,而NSOperationQueue(操作隊列)則在GCD之上實現了一些方便的功能,這些功能對開發人員而言通常是最好最安全的選擇.

隊列及操作:

    NSOperationQueue有兩種不同類型的隊列:主隊列和自訂隊列.

    主隊列運行在主線程上,自訂隊列在後台執行.

    隊列處理的任務是NSOperation的子類:NSInvocationOperation 和 NSBlockOperation.

NSOperation的基本使用步驟:

    定義操作隊列 --> 定義操作 -->將操作添加到隊列.

提示:

    一旦將操作添加到隊列,操作就會立即被調度執行.

NSInvocationOperation(調度操作)

    1> 定義隊列:

?
1 self.myQueue = [[NSOpertaionQueue alloc] init];

 

    2> 操作調用的方法:

?
1234 -(void)operationAction:(id)obj{    NSLog(@"%@----obj : %@ ",[NSThread currentThread], obj);};

 

    3> 定義操作並添加到隊列:

?
123 NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction:) object:@(i)];[self.myQueue addOperation:op]

 

提示:需要準備一個被調度的方法,並且能夠接收一個參數.

NSBlockOperation(塊操作)

     定義操作並添加到隊列:

?
1234 NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{    [self operationAction:@"Block Operation"];}];[self.myQueue addOperation:op];

 

    NSBlockOperation比NSInvocationOperation更加靈活;

設定作業的依賴關係:

    利用 " addDependency "可以指定操作之間彼此的依賴關係(執行先後順序),但是注意不要出現循環相依性.

設定同時並發的線程數量:

?
1 [self.myQueue setMaxConcurrentOperationCount:2];

 

NSOperation小結:

    從本質上看,操作隊列的效能會比GCD略低,不過,大多數情況下這點負面影響可以忽略不計.操作隊列是並發編程的首選工具.

    在這裡,推薦一個非常好用的第三方編程架構AFN,底層用GCD開發,開發的介面是NSOperation的.

多線程中得循環參考問題:

    如果self對象持有操作對象的引用,同時操作對象當中又直接存取了self時,才會造成循環參考.

    單純在操作對象中使用self不會造成循環參考.

注意:  此時不要使用[weakSelf].

多線程中的資源共用問題:

    並發編程中許多問題的根源就是在多線程中訪問共用資源.資源可以是一個屬性,一個對象,網路裝置或者一個檔案等.

    在多線程中任何一個共用的資源都可能是一個潛在的衝突點,必須精心設計以防止這種衝突的發生.

    為了保證效能,atomic僅針對屬性的setter方法做了保護.

    爭搶共用資源時,如果涉及到屬性的getter方法,可以使用互斥鎖(@synchronized)可以保證屬性在多個線程之間的讀寫都是安全的.

    無論是atomic還是@synchronized ,使用的代價都是高昂的.

建議:

    多線程是並發執行多個任務提高效率的,如果可能,應該線上程中避免爭搶共用資源.

    正是出於效能的考慮,UIKit中的絕大多數類都不是安全執行緒的,因此,蘋果公司要求:更新UI相關的操作,應該在主線程中執行.

NSObject的多線程方法

    1> 開啟後台執行任務的方法:

?
1 - (void)performSelectorInBackground:(SEL)@Selector withObject:(id)arg

 

    2> 在後台線程中通知主線程執行任務的方法:

?
1 - (void)performSelectorOnMainThread:(SEL)@Selector withObject:(id)arg waitUntilDone:(BOOL)wait

 

    3> 擷取線程資訊

?
1 [NSThread currentThread]

 

    4> 線程休眠

?
1 [NSThread sleepForTimeInterval:2.0f];

 

特點:

    1> 使用簡單,輕量級;

    2> 不能控制線程的數量以及執行順序.

NSObject的多線程方法注意事項:

    1> NSObject的多線程方法使用的是NSThread的多線程技術.

    2> NSThread的多線程技術不會自動使用@autoreleasepool.

在使用NSObject或NSThread的多線程技術時,如果涉及到對象分配,需要手動添加@autoreleasepool

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.