您好,登錄后才能下訂單哦!
靈活: GCD 具有在常見模式上(比如鎖、單例),用更高性能的方法優化代碼,而且 GCD 能提供更多的控制權力以及大量的底層函數。
性能: GCD 能自動根據系統負載來增減線程數量,這就減少了上下文切換以及增加了計算效率。
Dispatch Objects:
GCD是純C語言的,但它被組建成面向對象的風格。GCD對象被稱為dispatch object, 所有的dispatch objects都是OC對象.,就如其他OC對象一樣,當開啟了ARC(automatic reference counting)時,dispatch objects的retain和release都會自動執行。而如果是MRC的話,dispatch objects會使用dispatch_retain和dispatch_release這兩個方法來控制引用計數。
Serial & Concurrent:
串行任務就是每次只有一個任務被執行,并發任務就是在同一時間可以有多個任務被執行。
Synchronous & Asynchronous:
同步函數 意思是在完成了它預定的任務后才返回,在任務執行時會阻塞當前線程。而 異步函數 則是任務會完成但不會等它完成,所以異步函數不會阻塞當前線程,會繼續去執行下一個函數。
Context Switch:
Context Switch即上下文切換,一個上下文切換指當你在單個進程里切換執行不同的線程時存儲與恢復執行狀態的過程。這個過程在編寫多任務應用時很普遍,但會帶來一些額外的開銷。
Dispatch Queues:
GCD dispatch queues是一個強大的執行多任務的工具。Dispatch queue是一個對象,它可以接受任務,并將任務以先進先出(FIFO)的順序來執行。Dispatch queue可以并發的或串行的執行任意一個代碼塊,而且并發任務會像NSOperationQueue那樣基于系統負載來合適地并發進行,串行隊列同一時間則只執行單一任務。Dispatch queues內部使用的是線程,GCD 管理這些線程,并且使用Dispatch queues的時候,我們都不需要自己創建線程。Dispatch queues相對于和線程直接通信的代碼優勢是:Dispatch queues使用起來特別方便,執行任務更加有效率。
(1) 主線程隊列: main queue可以調用dispatch_get_main_queue()來獲得。因為main queue是與主線程相關的,所以這是一個串行隊列。和其它串行隊列一樣,這個隊列中的任務一次只能執行一個。它能保證所有的任務都在主線程執行,而主線程是唯一可用于更新 UI 的線程。
(2) 并發隊列: 并發隊列雖然是能同時執行多個任務,但這些任務仍然是按照先到先執行(FIFO)的順序來執行的。并發隊列會基于系統負載來合適地選擇并發執行這些任務。在iOS5之前,并發隊列一般指的就是全局隊列(Global queue),進程中存在四個全局隊列:高、中(默認)、低、后臺四個優先級隊列,可以調用dispatch_get_global_queue函數傳入優先級來訪問隊列。而在iOS5之后,我們也可以用dispatch_queue_create,并指定隊列類型DISPATCH_QUEUE_CONCURRENT,來自己創建一個并發隊列。
(3) 串行隊列: 串行隊列將任務以先進先出(FIFO)的順序來執行,所以串行隊列經常用來做訪問某些特定資源的同步處理。你可以也根據需要創建多個隊列,而這些隊列相對其他隊列都是并發執行的。換句話說,如果你創建了4個串行隊列,每一個隊列在同一時間都只執行一個任務,對這四個任務來說,他們是相互獨立且并發執行的。如果需要創建串行隊列,一般用dispatch_queue_create這個方法來實現。
介紹完基本概念,我們看看如何使用…..
(1) global queue(全局隊列):
當我們需要同時執行多個任務時,并發隊列是非常有用的。并發隊列其實仍然還是一個隊列,它保留了隊列中的任務按先進先出(FIFO)的順序執行的特點。一個并發隊列中實際執行的任務數是由很多因素決定的,比如系統的內核數,其他串行隊列中任務的優先級,以及其他進程的工作狀態。但是global queue 對于 dispatch_suspend(暫停)、dispatch_resume(恢復)、dispatch_set_context(切換上下文)函數無響應
我們來看一看 dispatch queue隊列的優先級都有哪些
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 //高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 //默認
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) //低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //后臺
注意:
盡管dispatch queues是引用計數對象,但是我們不需要用retain和release來管理全局的并發隊列。因為全局隊列對于程序來說是全局的,retain和release會被全局隊列忽略,而且在ARC下這兩個方法也會被忽略的。所以,我們不需要存儲這些隊列的引用數,僅僅只需要在任何要使用它們的地方,調用dispatch_get_global_queue這個方法即可。
(2) 并發隊列和串行隊列
當我們需要某些任務以指定的順序去執行時,串行隊列是一個非常好的選擇。一個串行隊列在同一時間里只會執行一個任務,而且每次都只會從隊列的頭部把任務取出來執行。正因為如此,我們可以用串行隊列來替代鎖的操作,比如數據資源的同步或修改數據結構時。和鎖不同的是,串行隊列能保證任務都是在可預見的順序里執行,而且一旦我們在一個串行隊列里異步提交了任務,隊列就能永遠不發生死鎖。怎么樣,是不是很棒,不過不像并發隊列,這些串行隊列是需要我們自己創建和管理的。
我們還可以在程序里創建任意數量的隊列,不過值得注意的是,我們要盡量避免創建大量的串行隊列而目的僅僅是為了同時執行隊列中的這些任務。雖然GCD 通過創建所謂的線程池來大致匹配 CPU 內核數量,但是線程的創建并不是無代價的。每個線程都需要占用內存和內核資源。所以如果需要創建大量的并發任務,我們只需要把這些任務放到并發隊列中即可。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。