IOS - 總結下swift使用GCD 多線程(二)GCD和DispatchQueue

來源:互聯網
上載者:User

標籤:固定   多核   作者   完成   shu   需要   spec   auto   nal   

1.前言

 iOS中處理多核並發的技術有兩種分別是:`Grand Central Dispatch`(以下簡稱`GCD`)和`NSOperationQueue`架構。iOS開發的老司機們在程式開發中處理多個任務同時執行的時候,一定都會使用到這兩個架構,而且GCD依靠它簡潔的文法和對block的運用一直很受大家的青睞。ios開發中你一定明白 這樣一條原則:“任何用於介面ui重新整理和使用者互動的操作都要放在主線程來操作,任何耗時或者耗CPU的任務必須在非同步線程去操作*”,----小白都會問為什要這樣,老司機都說記住就好-------這裡就簡單解釋下:  

首先我們來解釋第一句話:“任何用於介面ui重新整理和使用者互動的操作都要放在主線程來操作”,要明白這句話只要明白下面幾個點:1.主線程是安全執行緒的--把所有ui重新整理以及使用者的互動放在主線程操作會避免很多意外情況的發生,保證在擷取服務端返回的資料時,ui介面可以及時安全的重新整理資料,給使用者帶來良好體驗 。2.ios中只有主線程才可以立刻重新整理ui介面,如果放在非同步線程去操作都會造成線程阻塞和延遲的問題。---第二點“任何耗時或者耗CPU的任務必須在非同步線程去操作”---如果你很好的明白了前半句,那麼這句話的意思就很好理解了,把耗時或者消耗cpu的操作放在非同步線程,也就是為了防止線程的阻塞延遲,防止主線程上的ui重新整理和使用者操作的一系列動作出現卡頓,死結,延遲等問題。

2.本文

言歸正傳,我們繼續往下看,如果你對ios的中的GCD和DispatchQueue 使用很熟練的話,那麼swift3.0的文法和使用應該就是輕車熟路,如果你還不是特別明白GCD是什麼鬼?沒關係,這裡先給大家來點山裡的乾貨:

1. `dispatch queue`:一堆在主線程(或後台線程)上同步(或非同步)來執行的代碼,一旦被建立出來,作業系統就開始接手管理,在CPU上分配時間片來執行隊列內的代碼。開發人員沒法參與`queue`的管理。隊列採用`FIFO模式`(先進先出),意味著先加入的也會被先完成,這和超市排隊買單,隊伍前的總是最先買單出去,的道理是一樣一樣的。

2. `work item`:一段代碼塊,可以在queue建立的時候添加,也可以單獨建立方便之後複用,你可以把它當成將要在`queue`上啟動並執行一個代碼塊。`work items`也遵循著`FIFO模式`,也可以同步(或非同步)執行,如果選擇同步的方式,運行中的程式直到代碼塊完成才會繼續之後的工作,相對的,如果選擇非同步,運行中的程式在觸發了代碼塊就立刻返回了。

3. `serial`(串列)vs`concurrent`(並行):`serial`將會執行完一個任務才會開始下一個,`concurrent`觸發完一個就立即進入下一個,而不管它是否已完成。

接下來直奔主題:Swift3.0 中的GCD和DispatchQueue 使用。1.‘serial‘(串列) vs ‘concurrent‘(並行)   1.1 建立一個DispatchQueue的方法:
就是這麼簡單??

  label:後面是一個標識,可以隨便寫,一般建議寫成你的工程的dns的反序比較好。

   1.2 接下來我們建立一個串列的queue 和 在主線程中執行的代碼對比下看看串列隊列和主線程的區別?
??

然後我們在viewdidload中執行這個方法,看下控制台列印的結果:


??

從結果中我們可以看到兩個方法是一個一個按順序來執行的,也就是說串列隊列和主線程一樣都是串列輸出的。換句話說也就是:主線程也是一個串列隊列。

那非同步(並行)隊列執行會是怎麼樣呢?


非同步

看下輸出結果:


非同步結果

這次我們驚喜地發現和上次不同,並且主線程的函數和非同步隊列的函數是交替執行 也就是說二者同步的輸出,這是因為:非同步隊列不會阻塞當前線程 而是會另開一個線程來執行當前的任務,而主線程上的任務也就不會被阻塞,所以二者是同步輸出的。

通過上面的對比我們至少可以明白兩個件事:

1. 使用async主線程和後台線程可以並存執行任務

2. 使用sync則只能串列執行任務, 當前線程被卡住直到串列任務完成才繼續

2.GCD服務等級--Qos隊列

弄明白‘serial‘(串列) 和‘concurrent‘(並行)的關係,我們繼續來看下GCD的qos隊列。

GCD服務等級(GCD QoS):確定任務重要和優先順序的屬性

QoS是個基於具體情境的枚舉類型,在初始隊列時,可以提供合適的QoS參數來得到相應的許可權,如果沒有指定QoS,那麼初始方法會使用隊列提供的預設的QoS值

QoS等級(QoS classes),從前到後,優先順序從高到低:

userInteractive

userInitiated

default

utility

background

unspecified

從上面的介紹 我們猜想 肯定是 ---等級越高的隊列越先被執行,同一等級下的隊列中 串列隊列肯定是一個一個執行,非同步隊列肯定是分線程並存執行---下面我們就來驗證下:

2.1 首先建立一個Qos隊列:
qos隊列

qos:需要傳一個DispatchQoS的枚舉類型

2.2 同個隊列同等級串列輸出對比
qosConcurrentQueues

看下輸出結果:


qosConcurrentQueues-log

仔細觀察 我們會發現 結果並沒有像我們猜想的那樣 同等級下的非同步隊列 並行輸出,這是怎麼回事呢?因為Qos隊列預設是串列執行的,所以即使qos隊列中的方法是非同步 也會被順序串列執行。那麼怎樣才可以並存執行呢?這就要用到Qos隊列的另外一個屬性:attributes:.concurrent

具體寫法:


同等級並行
 

看下具體函數和運行結果:


同等級並行-log1

 


同等級並行-log2

通過輸出結果我們發現 結果是並行輸出了,但是細心的你是不是發現了結果中的一絲絲不同,附上的兩張結果圖,是同一個函數運行多次顯示的不同結果,為什麼會不同呢?難道程式有問題,一個函數怎麼可能有兩個結果呢?是不是頓時一臉懵逼,一萬個草泥馬在心中奔騰????????????????????????????????----施主息怒,待山裡娃慢慢給你分析:

首先我們要明白系統所謂的並存執行,並不全是我們想象那的樣是固定的像log1中的一樣十分規矩的輸出,內部是會發生資源的傾斜或者順序的不確定性,繼續看下去後面的例子你定會徹底明白。

我們建立一個不同等級的Qos隊列來看下結果:


不同等級qos

輸出結果:


不同等級qos-log3

觀察結果 ,我們會發現並不是我們之前猜測的 等級越高的隊列會快速先執行完,而是高等級和低等級的交叉進行輸出,仔細想下 其實這就是上面那個問題的完美詮釋,系統會使優先順序更高的`queue1`比`queue2`更快被執行,雖然在`queue1`啟動並執行時候`queue2`得到一個啟動並執行機會,系統還是將資源傾斜給了被標記為更重要的`queue1`,等`queue1`內的任務全部被執行完成,系統才開始全心全意服務於`queue2` 。---看到這裡應該明白了吧。

大家可以在思考個問題,在這些等級中 main queue主線程隊列是排在哪個等級呢?下面我們來看個例子:


main queue 對比

結果:


結果

從中我們可以清楚的得出結論:`main queue`預設就有一個很高的許可權。

接下來我們在來看下Qos隊列attributes的另外一個屬性,initiallyInactive (不活躍的),我們可以建立一個qos的不活躍隊列,這個隊列的特點是 需要調用DispatchQueue類的`activate()`讓任務執行。看下具體代碼:


initiallyInactive 隊列

重點在下面,viewdidload中調用:


initiallyInactive 隊列 調用

看下輸出結果:


initiallyInactive 隊列-log

我們發現隊列是串列輸出的,那麼怎樣建立一個並行的initiallyInactive 隊列呢?查看api我們會發現Qos隊列的attributes接收的是一個數組,所以聰明的你肯定知道怎麼辦吧??


initiallyInactive並行 隊列  3.順延強制

當你的應用的某個流程中的某項任務順延強制,GCD允許你執行某個方法來達到特定時間後運行你指定任務的目的。直接上代碼:


消極式載入

這裡解釋下:.now() 方法 是擷取目前時間。

4.DispatchWorkItem

DispatchWorkItem是一個代碼塊,它可以被分到任何的隊列,包含的代碼可以在後台或主線程中被執行,簡單來說:它被用於替換我們前面寫的代碼block來調用。使用起來也很簡單,看代碼:


DispatchWorkItem5.主線程更新UI

最後給大家分享一個開篇說到的主線程重新整理ui的例子,先看代碼:


主線程更新UI

使用的時候 記得在viewDidLoad 中調用setingIMage() 這個方法。

這裡主要想和大家介紹下swift中的懶載入和oc中的異同,個人總結了下大家可以參閱:


懶載入

山_裡_娃
連結:http://www.jianshu.com/p/737233208d40
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

IOS - 總結下swift使用GCD 多線程(二)GCD和DispatchQueue

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.