iOS有三種多線程編程的技術

1.NSThreadhtml

2.NSOperationQueuejava

3.GCD Threadios

是這三種範式裏面相對輕量級的,但也是使用起來最負責的,你須要本身管理thread的生命週期,線程之間的同步。線程共享同一應用程序的部份內存空間, 它們擁有對數據相同的訪問權限。你得協調多個線程對同一數據的訪問,通常作法是在訪問以前加鎖,這會致使必定的性能開銷。在 iOS 中咱們可使用多種形式的 thread: Cocoa threads: 使用NSThread 或直接從 NSObject 的類方法 performSelectorInBackground:withObject: 來建立一個線程。若是你選擇thread來實現多線程,那麼 NSThread 就是官方推薦優先選用的方式。 Cocoa operations是基於 Obective-C實現的,類 NSOperation 以面向對象的方式封裝了用戶須要執行的操做,咱們只要聚焦於咱們須要作的事情,而沒必要太操心線程的管理,同步等事情,由於NSOperation已經爲我 們封裝了這些事情。 NSOperation 是一個抽象基類,咱們必須使用它的子類。iOS 提供了兩種默認實現:NSInvocationOperation 和 NSBlockOperation。 Grand Central Dispatch (GCD): iOS4 纔開始支持,它提供了一些新的特性,以及運行庫來支持多核並行編程,它的關注點更高:如何在多個 cpu 上提高效率。git

 

 

具體實施程序員

 

這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。github

三種方式的優缺點介紹:
1)NSThread:
優勢:NSThread 比其餘兩個輕量級
缺點:須要本身管理線程的生命週期,線程同步。線程同步對數據的加鎖會有必定的系統開銷數據庫

NSThread實現的技術有下面三種:
~MA59HJ2_9MN7%]4Y%}FDGW
通常使用cocoa thread 技術。編程

Cocoa NSOperation
優勢:不須要關心線程管理,數據同步的事情,能夠把精力放在本身須要執行的操做上。
Cocoa operation 相關的類是 NSOperation ,NSOperationQueue。
NSOperation是個抽象類,使用它必須用它的子類,能夠實現它或者使用它定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation。
建立NSOperation子類的對象,把對象添加到NSOperationQueue隊列裏執行。網絡

GCD
Grand Central Dispatch (GCD)是Apple開發的一個多核編程的解決方法。在iOS4.0開始以後才能使用。GCD是一個替代諸如NSThread, NSOperationQueue, NSInvocationOperation等技術的很高效和強大的技術。如今的iOS系統都升級到7了,因此不用擔憂該技術不能使用。多線程

介紹完這三種多線程編程方式,本文將依次介紹這三種技術的使用。

(一)NSThread的使用
NSThread 有兩種直接建立方式:

第一個是實例方法,第二個是類方法

參數的意義:
selector :線程執行的方法,這個selector只能有一個參數,並且不能有返回值。
target  :selector消息發送的對象
argument:傳輸給target的惟一參數,也能夠是nil

第一種方式會直接建立線程而且開始運行線程,第二種方式是先建立線程對象,而後再運行線程操做,在運行線程操做前能夠設置線程的優先級等線程信息

不顯式建立線程的方法:
用NSObject的類方法  performSelectorInBackground:withObject: 建立一個線程:

下載圖片的例子:
新建singeView app
新建項目,並在xib文件上放置一個imageView控件。按住control鍵拖到viewController.h文件中建立imageView IBOutlet ViewController.m中實現:

線程間通信
線程下載完圖片後怎麼通知主線程更新界面呢?

performSelectorOnMainThread是NSObject的方法,除了能夠更新主線程的數據外,還能夠更新其餘線程的好比:

運行下載圖片:
VFE8W}]XP~E6K0RPJK10EIU

線程同步
咱們演示一個經典的賣票的例子來說NSThread的線程同步:

 

若是沒有線程同步的lock,賣票數多是-1.加上lock以後線程同步保證了數據的正確性。

上面例子我使用了兩種鎖,一種NSCondition ,一種是:NSLock。 NSCondition我已經註釋了。

線程的順序執行
他們均可以經過[ticketsCondition signal]; 發送信號的方式,在一個線程喚醒另一個線程的等待。

好比:

wait是等待,我加了一個 線程3 去喚醒其餘兩個線程鎖中的wait。

其餘同步
咱們可使用指令 @synchronized 來簡化 NSLock的使用,這樣咱們就沒必要顯示編寫建立NSLock,加鎖並解鎖相關代碼。

還有其餘的一些鎖對象,好比:循環鎖NSRecursiveLock,條件鎖NSConditionLock,分佈式鎖NSDistributedLock等等,能夠本身看官方文檔學習

NSThread下載圖片的例子代碼:http://download.csdn.net/detail/totogo2010/4591149

(二)Cocoa NSOperation的使用
使用 NSOperation的方式有兩種,
一種是用定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation。
另外一種是繼承NSOperation

若是你也熟悉Java,NSOperation就和java.lang.Runnable接口很類似。和Java的Runnable同樣,NSOperation也是設計用來擴展的,只需繼承重寫NSOperation的一個方法main。至關與java 中Runnalbe的Run方法。而後把NSOperation子類的對象放入NSOperationQueue隊列中,該隊列就會啓動並開始處理它。

NSInvocationOperation例子:
這裏一樣,咱們實現一個下載圖片的例子。新建一個Single View app,拖放一個ImageView控件到xib界面。
實現代碼以下:

代碼註釋:
1.viewDidLoad方法裏能夠看到咱們用NSInvocationOperation建了一個後臺線程,而且放到2.NSOperationQueue中。後臺線程執行downloadImage方法。
3.downloadImage 方法處理下載圖片的邏輯。下載完成後用performSelectorOnMainThread執行主線程updateUI方法。
updateUI 並把下載的圖片顯示到圖片控件中。

運行能夠看到下載圖片顯示在界面上。
thjyjytktfb464dfgbdgw4

第二種方式繼承NSOperation 
在.m文件中實現main方法,main方法編寫要執行的代碼便可。

如何控制線程池中的線程數?
隊列裏能夠加入不少個NSOperation, 能夠把NSOperationQueue看做一個線程池,可往線程池中添加操做(NSOperation)到隊列中。線程池中的線程可看做消費者,從隊列中取走操做,並執行它。

經過下面的代碼設置:

線程池中的線程數,也就是併發操做數。默認狀況下是-1,-1表示沒有限制,這樣會同時運行隊列中的所有的操做。

(三)GCD的介紹和使用
介紹:
Grand Central Dispatch 簡稱(GCD)是蘋果公司開發的技術,以優化的應用程序支持多核心處理器和其餘的對稱多處理系統的系統。這創建在任務並行執行的線程池模式的基礎上的。它首次發佈在Mac OS X 10.6 ,iOS 4及以上也可用。

設計:
GCD的工做原理是:讓程序平行排隊的特定任務,根據可用的處理資源,安排他們在任何可用的處理器核心上執行任務。

一個任務能夠是一個函數(function)或者是一個block。 GCD的底層依然是用線程實現,不過這樣可讓程序員不用關注實現的細節。

GCD中的FIFO隊列稱爲dispatch queue,它能夠保證先進來的任務先獲得執行。

dispatch queue分爲下面三種:
Serial 
又稱爲private dispatch queues,同時只執行一個任務。Serial queue一般用於同步訪問特定的資源或數據。當你建立多個Serial queue時,雖然它們各自是同步執行的,但Serial queue與Serial queue之間是併發執行的。

Concurrent 
又稱爲global dispatch queue,能夠併發地執行多個任務,可是執行完成的順序是隨機的。

Main dispatch queue 
它是全局可用的serial queue,它是在應用程序主線程上執行任務的。

咱們看看dispatch queue如何使用?

一、經常使用的方法dispatch_async
爲了不界面在處理耗時的操做時卡死,好比讀取網絡數據,IO,數據庫讀寫等,咱們會在另一個線程中處理這些操做,而後通知主線程更新界面。

用GCD實現這個流程的操做比前面介紹的NSThread  NSOperation的方法都要簡單。代碼框架結構以下:

若是這樣還不清晰的話,那咱們仍是用上兩篇博客中的下載圖片爲例子,代碼以下:

運行顯示:
fdgrehrthjytjasf4535gfn

是否是代碼比NSThread  NSOperation簡潔不少,並且GCD會自動根據任務在多核處理器上分配資源,優化程序。

系統給每個應用程序提供了三個concurrent dispatch queues。這三個併發調度隊列是全局的,它們只有優先級的不一樣。由於是全局的,咱們不須要去建立。咱們只須要經過使用函數dispath_get_global_queue去獲得隊列,以下:

這裏也用到了系統默認就有一個串行隊列main_queue:

雖然dispatch queue是引用計數的對象,可是以上兩個都是全局的隊列,不用retain或release。

二、dispatch_group_async的使用
dispatch_group_async能夠實現監聽一組任務是否完成,完成後獲得通知執行其餘的操做。這個方法頗有用,好比你執行三個下載任務,當三個任務都下載完成後你才通知界面說完成的了。下面是一段例子代碼:

dispatch_group_async是異步的方法,運行後能夠看到打印結果:

每一個一秒打印一個,當第三個任務執行後,upadteUi被打印。

三、dispatch_barrier_async的使用
dispatch_barrier_async是在前面的任務執行結束後它才執行,並且它後面的任務等它執行完成以後纔會執行
例子代碼以下:

打印結果:

請注意執行的時間,能夠看到執行的順序如上所述。

四、dispatch_apply 
執行某個代碼片斷N次。

本篇使用的到的例子代碼:http://download.csdn.net/detail/totogo2010/4596471
GCD還有不少其餘用法,能夠參考官方文檔http://en.wikipedia.org/wiki/Grand_Central_Dispatch

相關文章
相關標籤/搜索