GCD

有過編程經驗的人,基本都會接觸到多線程這塊。 java

在java中以及Android開發中,大量的後臺運行,異步消息隊列,基本都是運用了多線程來實現。 ios

一樣在,在ios移動開發和Android基本是很相似的一種模型。 編程

可是不少時候,在應用開發中,咱們會發現自己並無本身編碼去處理一些併發的事件,去開闢新的子線程等等。 api

(雖然通常的調用sdk發起一個網絡請求,系統都是會默認給你新起一個線程去處理的)。 數組

整個程序看上去基本就是在Main線程中執行。 安全

確實也是這樣的一種現象,由於咱們基本都是在操做控件的佈局,對控件數據添加,對於UI對象的更新都是在主線程的進行。 網絡

即使等下咱們看到咱們開啓了一個新的子線程用來獲取處理數據,最後仍是須要經過通知UI主線程來刷新。 多線程

固然了,ios自己也是和大部分語言同樣,有NSThread線程類(咱們都知道java中咱們用到這個類)。 併發

這些系統比較底層的api類,能夠被我用來書寫本身的併發線程和操做隊列。 異步

學過Android的咱們都知道Handler,Looper這個概念,Looper說白了就是一個主線程的消息循環隊列,handler通常理解就是用於子線程和UI主線程一些數據交互。

看了下ios的GCD特性,發現他們之間很有幾分類似。


 1.下面來看下如何使用gcd編程的異步

  1. dispatch_async(dispatch_get_global_queue(0, 0), ^{  
  2.     // 處理耗時操做的代碼塊...  
  3.       
  4.     //通知主線程刷新  
  5.     dispatch_async(dispatch_get_main_queue(), ^{  
  6.         //回調或者說是通知主線程刷新,  
  7.     });  
  8.       
  9. });  

dispatch_async開啓一個異步操做,第一個參數是指定一個gcd隊列,第二個參數是分配一個處理事物的程序塊到該隊列。

dispatch_get_global_queue(0, 0),指用了全局隊列。

通常來講系統自己會有3個隊列。

global_queue,current_queue,以及main_queue.

獲取一個全局隊列是接受兩個參數,第一個是我分配的事物處理程序塊隊列優先級。分高低和默認,0爲默認2爲高,-2爲低

  1. #define DISPATCH_QUEUE_PRIORITY_HIGH     2  
  2. #define DISPATCH_QUEUE_PRIORITY_DEFAULT  0  
  3. #define DISPATCH_QUEUE_PRIORITY_LOW     (-2)  

處理完事物後,須要將結果返回給或者是刷新UI主線程,一樣,和上面同樣,抓取主線程,程序塊操做。


//天啊,手賤不當心點到了home間,會退後發現沒保存~~~寫的併發一塊內容都沒了!!!

二:GCD之併發概念

其實對於編程中,咱們一直說起到的幾個概念,同步,異步,併發,鎖等。

有時以爲一會兒還真說不清。


下面咱們以上面提到的圖片加載來看下這3個概念個人理解

1同步:

  1. for (int i = 0 ; i < 10; i++) {  
  2.      
  3.       UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];  
  4.        [myImgV[i] setImage:img];  
  5.        
  6.  }  

假設我要加載10個圖片,我如今擁有這些圖片的資源地址,保存在一個數組中。

咱們先以獲取第一張圖片來舉例:

同步執行的概念就是,我獲取完第一張圖片的,

執行了for循環第一句返回了img後,我才能執行第二句,UI界面的刷新。

若是第一句返回的時間須要10秒,那我程序的響應就彷彿一直卡在這裏同樣,我沒法進行其餘操做。必須等它返回!!

所以,同步的一個很好理解的感念就是,一步走到黑。

2.異步

  1. for (int i = 0 ; i < 10; i++) {  
  2.       dispatch_async(dispatch_get_global_queue(0, 0), ^{  
  3.       // 處理耗時操做的代碼塊...  
  4.        UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];  
  5.       //通知主線程刷新  
  6.       dispatch_async(dispatch_get_main_queue(), ^{  
  7.           //回調或者說是通知主線程刷新,  
  8.             [myImgV[i] setImage:img];  
  9.       });  
  10.         
  11.   });  

看了這代碼,咱們會說,異步操做那個假設仍是要10秒啊,整體看來,執行一張圖片的時間加載仍是要在10秒左右啊,

貌似異步沒什麼鳥用麼。可是,別忽略了其中一點,也黑絲核心的一點,此時咱們圖片獲取操做放在裏一個線程隊列裏,

此刻,雖然咱們看着圖片的加載仍是須要10秒纔會出來,可是,在這10秒期間,咱們的UI主線程是能夠操做的,好比界面上有個按鈕,你是能夠按的

而不是如上面的同步,在10面期間,我是隻能幹等着,什麼都作不了。

異步的核心概念就是一個新線程,一個消息回調通知。

3.並行

咱們仍是以上代碼爲例。前面我強調了,咱們只看一張圖片的加載,如今,回到咱們第一眼看到代碼的思惟上去,

一個for循環。其實上面代碼事後,我是建立了10個異步線程。

好吧,到此,咱們應該明白這三個概念了。

同步,其實我前面的例子舉得有些侷限,就是這個例子自己就說明不須要同步執行,而後給你們大感受是

同步是編程中一個忌諱點同樣,其實否則,不少時候。咱們真是須要同步來作一些限制(好比線程中提出的同步鎖?聽着就感受有用麼

雖然可能並不如咱們想的那樣的運用同步,可是至少說明這個概念一樣是有用的)

我仍是以剛纔那個加載圖片爲例子,來個簡單的說明如何運用同步的好處。

固然,我只是模擬一個同步的狀況。

假設咱們如今圖片的加載是這樣的,圖片自己爲在加載前是一個默認的圖片,上面寫着,點擊我加載,點擊後會調用網絡加載方法,而後圖片顯示加載中,

而後咱們雙擊圖片時(固然,理論上是在加載完後)讀取圖片網絡圖片放大,好吧,到這裏應該能想到要表達的狀況了。

整個流程應該是點擊圖片->加載->雙擊查看。那若是成了點擊->加載中(以返回了圖片的做者和信息)-》雙擊圖片(經過前面請求返回的大圖連接顯示大圖)-》

徹底加載返回(返回了大圖連接)。此時咱們看不到圖像的大圖了。由於咱們操做在返回前了,也就是說,

不少時候,咱們下一個動做的操做必須須要用到前面一個操做的數據時,咱們會給他作認爲的同步編程,好比加個按鈕鎖。

這是咱們又會疑惑道,下一個執行須要用到前一個執行的,那第一個例子中的for循環的第二句不是要用到麼,這麼說

他們必需要同步啊,若是你這麼想了,好巧,咱們想到一塊去了~

可是,注意,前面咱們到的異步是爲了解決我點擊其餘按鈕的操做,而不是說更新UI操做。下載和更新UI操做在咱們看來必須是同步的

這是對的,可是那種作致使了系統自己一些監聽事件監聽到點擊處理在那個請求以後了,這邊的加載圖片其實要當作一次事件執行,

由於對於事件的這一抽象單元,實際上是一種可人爲定義的寬廣度。

也就是說,一次數據獲取和圖像填充,其實算是一個圖像獲取加載事件,事件能夠說包含兩個單元,加載和填充。

而整個這個事件對於咱們點擊其餘按鈕並沒有關係,那麼也就說明了無需同步。

有道理啊,可是若果咱們要點擊這個圖片呢,也就是回到剛纔那個能夠雙擊的假設。

此處也許我麼又忽略了一點爲何加載中咱們能點擊雙擊呢,也就這樣的假設是獲取圖片已經作了異步,可是咱們下一步操做又是須要同步的

所以作了人爲的同步鎖定。

好了,說的太多了,當時至少咱們明白兩點

異步多是爲了反正耗時操做形成的主線程堵塞,

同步是爲了解決一些沒必要要錯誤和麻煩。也許到這裏,咱們腦中會聯想到的所謂的線程安全性。

其實同步以及同步鎖,倒是應該是考慮到這樣的沒必要要和不安全因素。


最後在簡單闡述下異步和併發關係。

其實看了上面說的,異步只是提供了一種多線程處理的概念,

併發是更像是異步的一種大規模實現。

就比如說,異步提出了能夠用小弟去收保護費,收完了告訴並交給本身,而我在期間作其餘要作的事。

併發忽然想到,異步這個頗有道理啊,那我有4個地方要收,一個小弟去收,雖然我仍是能夠閒着作其餘的事,

可是小弟跑四個地方,我拿到錢所須要的時間仍是和我本身去收同樣的,只不過我不用那麼費勁了,還能作其餘事了。

所以,併發以爲應該派四個小弟去,由於每一個場地的保護費各不相干的。(剛看了個紐約黑幫~)。


所以說,異步解決了線程堵塞,而併發則是在異步的基礎上,提升了符合特性事件的處理時間效率。


固然,若是10個圖片自己相互間是沒什麼聯繫,可是,最後一個事件須要處理計算這10個圖片的總容量值。

那麼能夠用 dispatch_group_async。

具體就看文檔吧。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息