這裏有幾個實驗,我已經做了讓我瞭解這些serial
,concurrent
隊列與Grand Central Dispatch
。
func doLongAsyncTaskInSerialQueue() {
let serialQueue = DispatchQueue(label: "com.queue.Serial")
for i in 1...5 {
serialQueue.async {
if Thread.isMainThread{
print("task running in main thread")
}else{
print("task running in background thread")
}
let imgURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
let _ = try! Data(contentsOf: imgURL)
print("\(i) completed downloading")
}
}
}
任務將在不同的線程(不是主線程等),當您在使用GCD異步運行。異步意味着執行下一行不要等到塊執行後,結果非阻塞主線程&主隊列。 由於它的串行隊列,所有都按照它們添加到串行隊列的順序執行。串行執行的任務總是由與隊列關聯的單個線程一次執行一個。
func doLongSyncTaskInSerialQueue() {
let serialQueue = DispatchQueue(label: "com.queue.Serial")
for i in 1...5 {
serialQueue.sync {
if Thread.isMainThread{
print("task running in main thread")
}else{
print("task running in background thread")
}
let imgURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
let _ = try! Data(contentsOf: imgURL)
print("\(i) completed downloading")
}
}
}
任務可以在主線程中運行,當你在GCD使用同步。 Sync會在給定隊列上運行一個塊,並等待它完成,從而導致阻塞主線程或主隊列。由於主隊列需要等到分派塊完成,因此主線程將可用於處理除隊列之外的隊列主隊列。因此有可能在後臺隊列上執行代碼實際上可能在主線程上執行 由於其串行隊列,所有這些隊列都按照它們添加的順序(FIFO)執行。
func doLongASyncTaskInConcurrentQueue() {
let concurrentQueue = DispatchQueue(label: "com.queue.Concurrent", attributes: .concurrent)
for i in 1...5 {
concurrentQueue.async {
if Thread.isMainThread{
print("task running in main thread")
}else{
print("task running in background thread")
}
let imgURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
let _ = try! Data(contentsOf: imgURL)
print("\(i) completed downloading")
}
print("\(i) executing")
}
}
任務將在後臺線程,當你在GCD使用異步運行。異步意味着執行下一行不要等到塊執行,這會導致非阻塞主線程。 在併發隊列中記住,任務按照它們被添加到隊列中的順序進行處理,但隊列中附加了不同的線程。請記住,它們不應該按照 的順序完成任務,它們將被添加到隊列中。任務的順序每次都不相同 必須自動創建線程。任務並行執行。如果超過 (maxConcurrentOperationCount),則某些任務將作爲串行行爲 ,直到線程空閒爲止。
func doLongSyncTaskInConcurrentQueue() {
let concurrentQueue = DispatchQueue(label: "com.queue.Concurrent", attributes: .concurrent)
for i in 1...5 {
concurrentQueue.sync {
if Thread.isMainThread{
print("task running in main thread")
}else{
print("task running in background thread")
}
let imgURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
let _ = try! Data(contentsOf: imgURL)
print("\(i) completed downloading")
}
print("\(i) executed")
}
}
任務可以在主線程中運行,當你在GCD使用同步。 Sync會在給定隊列上運行一個塊,並等待它完成,從而導致阻塞主線程或主隊列。由於主隊列需要等到分派塊完成,因此主線程將可用於處理除隊列之外的隊列主隊列。因此有可能在後臺隊列上執行的代碼實際上可能正在主線程上執行。 由於其併發隊列,任務可能無法按照它們添加到隊列的順序完成。但是在同步操作中,儘管它們可能由不同的線程處理。所以,它表現爲這是串行隊列。
下面是這個實驗
的總結記住使用GCD你只添加任務隊列,並從隊列中執行任務。隊列根據操作是同步還是異步來分派主任務或後臺線程中的任務。隊列類型爲串行,併發,主調度隊列。所有執行的任務都默認從主調度隊列完成。已經有4個預定義的全局併發隊列供您的應用程序使用,並且有一個主隊列(DispatchQueue.main)。您也可以手動創建自己的隊列並從該隊列執行任務。
UI通過分派任務主要queue.Short手工具的任務應始終從主線程執行相關的DispatchQueue.main.sync/async
而與網絡相關的/重操作應該總是做異步沒有哪個曾經線程使用的是主或事項背景
編輯: 然而,有需要執行網絡調用後臺線程同步操作,而沒有凍結UI的情況下(egrefreshing OAuth令牌,然後等待,如果它成功與否)。你需要來包裝方法在異步操作中。這樣,您的繁重操作就按順序執行,並且不會阻塞mai n線程。
func doMultipleSyncTaskWithinAsynchronousOperation() {
let concurrentQueue = DispatchQueue(label: "com.queue.Concurrent", attributes: .concurrent)
concurrentQueue.async {
let concurrentQueue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default)
for i in 1...5 {
concurrentQueue.sync {
let imgURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
let _ = try! Data(contentsOf: imgURL)
print("\(i) completed downloading")
}
print("\(i) executed")
}
}
}
編輯編輯:您可以觀看演示視頻here
一個簡單的好前提的問題[調度同步VS異步(http://stackoverflow.com/questions/9200558/grand-central-dispatch-async-vs-sync) – Honey