2017-02-04 44 views
0

我在斯威夫特新秀,有這樣的誤解是什麼方式,創造DispatchQueue Swift3

有什麼區別如何創建調度隊列中的差異

樣品1

let backgroundQueue = DispatchQueue(label: "com.app.queue", 
           qos: .background, 
           target: nil) 

backgroundQueue.async { 
print("Dispatched to background queue") 
} 

樣本2

let backgroundQueue = DispatchQueue.global() 
backgroundQueue.async { 
print("Dispatched to background queue") 
} 

據我所知,這兩種方法做同樣的

,或者例如這種做法

DispatchQueue.global(qos: .userInitiated).async { 
print("user initiated task") 
} 

這是什麼意思?

回答

1

您在第一個示例中創建的隊列是您自己的自定義串行隊列。由於有些過時,但仍然相關,Concurrency Programming Guide說:

串行隊列(也稱爲私有調度隊列)在它們添加到隊列的順序一次執行一個任務。當前正在執行的任務運行在由調度隊列管理的不同線程上(可能因任務而異)。串行隊列通常用於同步對特定資源的訪問。

您可以根據需要創建儘可能多的串行隊列,並且每個隊列都可以與所有其他隊列同時運行。換句話說,如果你創建了四個串行隊列,每個隊列一次只執行一個任務,但最多可以同時執行四個任務,每個隊列一個。

儘管你的後者的例子是使用簡單地檢索系統提供的全局隊列,其是併發:

併發隊列(也被稱爲類型全局調度隊列的)執行一個或多個任務同時,但任務仍按其添加到隊列的順序啓動。當前正在執行的任務在由調度隊列管理的不同線程上運行。在任何給定點執行的任務的確切數量是可變的,並取決於系統條件。

現在,您現在可以創建自己的自定義併發隊列,但全局隊列僅僅是爲我們創建的併發隊列。

那麼,這對你意味着什麼?

  • 如果您將塊分派到串行隊列(您的第一個示例),則任何時候都只能運行一個塊。這對於同步多線程應用程序中的內存訪問非常有用,但可用於需要後臺隊列的任何環境,但希望調度的塊相對於該隊列上的其他塊連續運行(即按順序) 。

  • 您在後面的示例中使用的全局隊列是併發隊列。這意味着如果您將四個單獨的任務分派給此全局隊列,那麼這些塊可能會相對於彼此同時運行)。如果你真的想要不僅僅是後臺執行,而且不關心這些模塊是否也與其他調度模塊同時運行,那麼這是非常理想的。

  • 在你後面的例子,在那裏你訪問一個全球性的隊列,要認識到,因爲這些都是系統提供的,你必須與這些隊列中的互動,即一些適度的限制:

    • 你不能暫停全局隊列;

    • 您不能在全局隊列中使用障礙;
       

    但是,與儘管如此,如果你只是尋找調度塊在後臺運行的一個簡單的方法(如果這些派遣塊在同一時間,因爲每個運行你不在乎其他),那麼全球隊列是非常簡單而有效的方法。


順便說一句,你的第二個例子之間(對於我假設你打算let backgroundQueue = DispatchQueue.global())和第三個例子的差別,僅僅是在你的第三個例子,你指定的服務的明確的質量( qos),而在第二個例子中,您使用的是默認的qos。 FWIW,通常建議指定一個qos,以便操作系統可以優先處理爭用有限系統資源的線程。

+0

請你解釋一下,如果我正確理解了這個參數'qos:'我們只需要說OS關於隊列優先級? –

+0

我不確定你的問題是什麼問題,但我可能會推薦你參加WWDC 2015 [使用GCD構建響應式和高效應用程序](https://developer.apple.com/videos/play/wwdc2015/718/) ,它將向您介紹qos概念。我們的想法是,您可以指定GCD在高爭用環境中如何優先處理,並提供一個非常簡單的界面來控制各種變量,包括針對您的特定硬件調整的CPU調度優先級,I/O優先級,定時器合併等。 – Rob

0

的3

樣品1之間沒有太大的區別創建只有您的應用程序訪問的隊列。您還可以將其標籤設置爲com.app.queue,這可以幫助您更輕鬆地進行調試。

示例2是無效的Swift代碼。我相信你的意思是:

let backgroundQueue = DispatchQueue.global(qos: .default) // or any other QoS 

backgroundQueue.async { 
    print(backgroundQueue.label) // the label property tell you what queue it is 
} 

與樣本1相同,請接受您正在使用與其他應用程序共享的系統隊列。

樣品3僅僅是一個方便的方法(除所指定的不同的QoS):

DispatchQueue.global(qos: .userInitiated).async { 
    // you don't have any reference to the queue your code 
    // is running on, but most of times it's not needed 
} 

大多數我寫使用類似的東西到樣品3樣品2是最不常見的代碼。示例1主要用於需要跨多個隊列同步操作的情況。

+0

請問您能解釋一下,只屬於我的應用和系統的隊列有什麼區別?另一個關於樣本3,我的意思是'.userInitiated'和'.default'之間的區別? –

相關問題