GCD 一直以來(lái)是基于 c 語(yǔ)言的。
apple 為了使 GCD 使用更加的 swift 化。 對(duì) GCD 進(jìn)行了進(jìn)行了改造。
以下所有代碼都是基于 Swift3.0
先來(lái)段廢話:
(不了解基本概念的建議看看, 了解的直接略過(guò)!)
GCD
Grand Central Dispatch (GCD)是Apple開(kāi)發(fā)的一個(gè)多核編程的較新的解決方法。它主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對(duì)稱多處理系統(tǒng)。它是一個(gè)在線程池模式的基礎(chǔ)上執(zhí)行的并行任務(wù)。在Mac OS X 10.6雪豹中首次推出,也可在IOS 4及以上版本使用。
GCD 中兩個(gè)重要重要概念 —— 隊(duì)列 & 任務(wù)
隊(duì)列
隊(duì)列是一種特殊的線性表,采用FIFO(先進(jìn)先出)的原則,即新任務(wù)總是被插入到隊(duì)列的末尾,而讀取任務(wù)的時(shí)候總是從隊(duì)列的頭部開(kāi)始讀取。每讀取一個(gè)任務(wù),則從隊(duì)列中釋放一個(gè)任務(wù)。
隊(duì)列的主要作用是用來(lái)存放任務(wù)。
GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出,放到對(duì)應(yīng)的線程中執(zhí)行。
**隊(duì)列分類: **
串行隊(duì)列(Serial Dispatch Queue): 讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
并發(fā)隊(duì)列(Concurrent Dispatch Queue): 可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開(kāi)啟多個(gè)線程同時(shí)執(zhí)行任務(wù)), 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
> 由于隊(duì)列同步執(zhí)行不具有開(kāi)啟線程的能力,異步執(zhí)行才可以開(kāi)啟線程。
> 并發(fā)隊(duì)列在異步執(zhí)行才有效。
隊(duì)列執(zhí)行任務(wù)的方式:
同步:在當(dāng)前線程中執(zhí)行,當(dāng)前代碼不執(zhí)行完,就不能夠執(zhí)行下一條代碼。會(huì)阻塞當(dāng)前線程。
異步:在另一條線程中執(zhí)行(不用等待當(dāng)前代碼執(zhí)行完,就能夠執(zhí)行下一條),不會(huì)阻塞當(dāng)前線程。
常見(jiàn)隊(duì)列:
為了方便 GCD 使用,蘋果默認(rèn)提供了主隊(duì)列和全局隊(duì)列。 我們不需要?jiǎng)?chuàng)建只需要獲取。
- 主隊(duì)列 (串行)
let mainQueue = DispatchQueue.main
- 全局隊(duì)列 (并發(fā))
let globalQueue = DispatchQueue.global()
全局隊(duì)列默認(rèn)是并發(fā)隊(duì)列,在不進(jìn)行第三方框架或者大型的商業(yè)應(yīng)用開(kāi)發(fā),全局隊(duì)列基本夠用。
任務(wù)
需要執(zhí)行操作, 任務(wù)是使用閉包( oc: block) 封裝的代碼塊。
廢話到此完畢!
1. 項(xiàng)目開(kāi)發(fā)中 GCD 代碼使用
print("DispatchQueue.main.sync: befor", Thread.current)
DispatchQueue.global().async {
print("DispatchQueue.global().async: Time task", Thread.current, "\n --: 耗時(shí)操作在后臺(tái)線程中執(zhí)行!")
DispatchQueue.main.async {
print("DispatchQueue.main.async: update UI", Thread.current, "\n --: 耗時(shí)操作執(zhí)行完畢后在主線程更新 UI 界面!")
}
}
print("DispatchQueue.main.sync: after", Thread.current)
// 打?。?DispatchQueue.main.sync: befor <NSThread: 0x60800007abc0>{number = 1, name = main}
DispatchQueue.main.sync: after <NSThread: 0x60800007abc0>{number = 1, name = main}
DispatchQueue.global().async: Time task <NSThread: 0x6080002662c0>{number = 3, name = (null)}
--: 耗時(shí)操作在后臺(tái)線程中執(zhí)行!
DispatchQueue.main.async: update UI <NSThread: 0x60800007abc0>{number = 1, name = main}
--: 耗時(shí)操作執(zhí)行完畢后在主線程更新 UI 界面!
/*
after 執(zhí)行的先后順序是不確定的。是由 GCD 決定。
這里牽扯到一個(gè)概念: 線程間通訊! 說(shuō)白的就是在線程間進(jìn)行數(shù)據(jù)(信號(hào))的傳遞。
*/
如果你只是單純的找 GCD 在 swift 中怎么使用,看到這里你基本可以關(guān)掉這篇博客,開(kāi)心的寫(xiě)代碼去了。
2. GCD 使用 —— 精講
先來(lái)了解 GCD 在 Swift 中的變化
GCD 框架頭文件改變
import Dispatch.base // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.block // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.data // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.group
import Dispatch.io
import Dispatch.object
import Dispatch.once // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.queue
import Dispatch.semaphore
import Dispatch.source
import Dispatch.time
import Dispatch
import os_object
// 在 swift3.0 中新加的, OS_object 繼承自 NSObject
// 在 GCD 中所有的對(duì)象都間接的繼承自 NSObject。
import os_object
open class OS_object : NSObject {
}
Swift 中最大的變化其實(shí)就是更加的面相對(duì)象了,使用更加的方便簡(jiǎn)潔,擺脫了 OC 時(shí)代函數(shù)式的使用方式。
GCD 使用先來(lái)個(gè)個(gè)人小的總結(jié):
口訣:同步不開(kāi)異步開(kāi),串行開(kāi)1條,并行開(kāi)多條。
來(lái),跟著哥一起念。( 我怕你們打我,你們還是別念了,我解釋一下。)
同步不開(kāi)異步開(kāi),串行開(kāi)1條,并行開(kāi)多條。
單純這么簡(jiǎn)單的看是有誤解的, 在我的評(píng)論中就可以看到。
具體的意思是:
隊(duì)列中的任務(wù)同步執(zhí)行,隊(duì)列就不具有開(kāi)啟線程的能力, 隊(duì)列中的任務(wù)異步執(zhí)行,隊(duì)列就具有開(kāi)啟線程的能力。
(同步和異步執(zhí)行決定的是否有開(kāi)啟線程的能力)
如果隊(duì)列具 **有開(kāi)啟線程的能力 (隊(duì)列任務(wù)異步執(zhí)行) ** 且隊(duì)列是 串行隊(duì)列 ,那么將會(huì) 開(kāi)啟 1 條線程 。
如果隊(duì)列具 **有開(kāi)啟線程的能力 (隊(duì)列任務(wù)異步執(zhí)行) ** 且隊(duì)列是 并發(fā)隊(duì)列 ,那么將會(huì) 開(kāi)啟 多 條線程 。開(kāi)啟線程的條數(shù)由 GCD 決定。
** ( 串行和并發(fā)決定的是開(kāi)幾條線程 ) **
** 如果真正理解了上面這些,多 GCD 的使用和面試基本沒(méi)什么障礙。 **
2.1 全局隊(duì)列
全局隊(duì)列是獲取的,不是程序員創(chuàng)建的。
為了方便 GCD 的使用,apple 默認(rèn)為我們提供的。
全局隊(duì)列默認(rèn)是并發(fā)隊(duì)列,在不是進(jìn)行第三方框架或者大型的商業(yè)應(yīng)用開(kāi)發(fā),全局隊(duì)列基本夠用。
全局 ( 并發(fā) ) 隊(duì)列異步執(zhí)行 :
并發(fā)隊(duì)列異步(不阻塞當(dāng)前線程)執(zhí)行(隊(duì)列就具有開(kāi)啟線程的能力), 隊(duì)列會(huì)開(kāi)啟多條線程。
任務(wù)異步執(zhí)行不會(huì)阻塞當(dāng)前線程,
befor 在最前,
after 在任意位置,
task 執(zhí)行順序不確定 —— 并發(fā)執(zhí)行(index可以確認(rèn))。
task 并發(fā)執(zhí)行 —— 并發(fā)執(zhí)行(number可以確認(rèn))。
異步開(kāi)線程 number 可以確定開(kāi)啟了多條線程
開(kāi)的線程數(shù)由 GCD 決定。 可以看到線程的 number 有重復(fù),是 GCD 對(duì)線程進(jìn)行了復(fù)用。
func async() {
print("DispatchQueue.global().async: befor", Thread.current)
// 全局隊(duì)列進(jìn)行 10次異步
for index in 0..<10 {
DispatchQueue.global().async {
print("DispatchQueue.global().async: task:(taskIndex:\(index)", Thread.current)
}
}
print("DispatchQueue.global().async: after", Thread.current)
}
打?。? DispatchQueue.global().async: befor <NSThread: 0x60800006a8c0>{number = 1, name = main}
DispatchQueue.global().async: task:(taskIndex:1 <NSThread: 0x600000079780>{number = 3, name = (null)}
DispatchQueue.global().async: task:(taskIndex:2 <NSThread: 0x6000000797c0>{number = 4, name = (null)}
DispatchQueue.global().async: task:(taskIndex:0 <NSThread: 0x600000079880>{number = 5, name = (null)}
DispatchQueue.global().async: task:(taskIndex:3 <NSThread: 0x608000074e00>{number = 6, name = (null)}
DispatchQueue.global().async: task:(taskIndex:4 <NSThread: 0x600000079780>{number = 3, name = (null)}
DispatchQueue.global().async: task:(taskIndex:5 <NSThread: 0x6000000797c0>{number = 4, name = (null)}
DispatchQueue.global().async: after <NSThread: 0x60800006a8c0>{number = 1, name = main}
DispatchQueue.global().async: task:(taskIndex:6 <NSThread: 0x600000079880>{number = 5, name = (null)}
DispatchQueue.global().async: task:(taskIndex:7 <NSThread: 0x608000074e00>{number = 6, name = (null)}
DispatchQueue.global().async: task:(taskIndex:8 <NSThread: 0x600000079780>{number = 3, name = (null)}
DispatchQueue.global().async: task:(taskIndex:9 <NSThread: 0x6000000797c0>{number = 4, name = (null)}
全局 ( 并發(fā) ) 隊(duì)列同步執(zhí)行 :
并發(fā)隊(duì)列同步(阻塞當(dāng)前線程)執(zhí)行(隊(duì)列就不具有開(kāi)啟線程的能力), 隊(duì)列不會(huì)開(kāi)啟線程(代碼都在主線程中執(zhí)行)。
任務(wù)同步執(zhí)行會(huì)阻塞當(dāng)前線程,
befor 在最前,
after 在最后,
task 執(zhí)行順序確定 —— 阻塞。
同步?jīng)]有開(kāi)啟線程 number 可以確定沒(méi)有開(kāi)啟多條線程。所有的代碼都在 主線程中執(zhí)行。
func sync() {
print("DispatchQueue.global().sync: befor", Thread.current)
for index in 0..<10 {
DispatchQueue.global().sync {
print("DispatchQueue.global().sync: task:(taskIndex:\(index))", Thread.current)
}
}
print("DispatchQueue.global().sync: after", Thread.current)
}
打?。?
DispatchQueue.global().sync: befor <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:0) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:1) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:2) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:3) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:4) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:5) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:6) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:7) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:8) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:9) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: after <NSThread: 0x60800007fa80>{number = 1, name = main}
2.2 主隊(duì)列
主隊(duì)列是獲取的,不是程序員創(chuàng)建的,apple 默認(rèn)為我們提供的。
(app 開(kāi)發(fā)中,所有的 UI 更新操作都應(yīng)該在主線程中進(jìn)行)
主隊(duì)列(串行)異步執(zhí)行
主隊(duì)列異步(不會(huì)阻塞當(dāng)前線程)執(zhí)行(隊(duì)列就具有開(kāi)啟線程的能力), 隊(duì)列會(huì)開(kāi)啟線程(開(kāi)啟的線程就是主線程)。
> 有朋友問(wèn)我,異步會(huì)開(kāi)啟線程, 主隊(duì)列異步就不會(huì)開(kāi)啟線程。
> 我當(dāng)時(shí)還信以為真。認(rèn)為自己錯(cuò)誤,說(shuō)特殊情況特殊處理。 其實(shí)說(shuō)白了就是學(xué)藝不精。
> 由于主隊(duì)列是我們獲取的,不是我們創(chuàng)建的,在某種意識(shí)中會(huì)認(rèn)為主線程不是在主隊(duì)列中創(chuàng)建的。(認(rèn)為一開(kāi)始就存在的。)
> 任務(wù)異步執(zhí)行不會(huì)阻塞當(dāng)前線程,
befor 在最前,
after 在第二,
task 執(zhí)行順序確定 —— 串行執(zhí)行(index可以確認(rèn))。
同步?jīng)]有開(kāi)啟線程 number 可以確定沒(méi)有開(kāi)啟多條線程。所有的代碼都在 主線程中執(zhí)行。
主隊(duì)列異步的操作主要用在更新 UI 操作中。 具體參考 項(xiàng)目開(kāi)發(fā)中 GCD 代碼使用。
func async() {
print("DispatchQueue.main.async: befor", Thread.current)
for index in 0..<10 {
DispatchQueue.main.async {
print("DispatchQueue.main.async: task:(taskIndex:\(index)", Thread.current)
}
}
print("DispatchQueue.main.async: after", Thread.current)
}
打?。?
DispatchQueue.main.async: befor <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: after <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:0 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:1 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:2 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:3 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:4 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:5 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:6 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:7 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:8 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:9 <NSThread: 0x60800006ddc0>{number = 1, name = main}
主隊(duì)列(串行)同步執(zhí)行
執(zhí)行的效果就倆字 ** 死鎖**
主線程同步,在 Swift 中,編譯階段就報(bào)錯(cuò),在 oc 中是在運(yùn)行的時(shí)候才能發(fā)現(xiàn)。體現(xiàn)的主要是界面的 “假死”。

2.3 自定義隊(duì)列
/*
label: 隊(duì)列名稱
qos: 服務(wù)質(zhì)量
// 后臺(tái)優(yōu)先級(jí)
public static let background: DispatchQoS
// 實(shí)用工具優(yōu)先級(jí)別(耗時(shí)操作,可以使用這個(gè))
public static let utility: DispatchQoS
// 默認(rèn)優(yōu)先級(jí)(一般不是給程序員實(shí)用的,用來(lái)重置隊(duì)列用的)
public static let `default`: DispatchQoS
// 用戶期望優(yōu)先級(jí)(不要放太耗時(shí)的操作)
public static let userInitiated: DispatchQoS
// 用戶交互(希望盡快完成,用戶很希望得到結(jié)果。個(gè)人覺(jué)得這個(gè)和主線的的線程優(yōu)先級(jí)是一樣的)
public static let userInteractive: DispatchQoS
// 未指定
public static let unspecified: DispatchQoS
attributes: 隊(duì)列屬性
// 并發(fā)
public static let concurrent: DispatchQueue.Attributes
// 初始化不活躍
public static let initiallyInactive: DispatchQueue.Attributes
autoreleaseFrequency: 自動(dòng)釋放頻率
public enum AutoreleaseFrequency {
// 繼承
case inherit
// 工作項(xiàng)
case workItem
// 從來(lái)沒(méi)有,永遠(yuǎn)不
case never
}
target: 目標(biāo)隊(duì)列
( 這些參數(shù)我也沒(méi)搞明白)
*/
public convenience init(label: String,
qos: DispatchQoS = default,
attributes: DispatchQueue.Attributes = default,
autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = default,
target: DispatchQueue? = default)
在沒(méi)有搞明白參數(shù)的時(shí)候,由于 swift 可以使用默認(rèn)參數(shù), 我們可以使用默認(rèn)參數(shù)。
自定義(串行)隊(duì)列異步執(zhí)行
// 使用默認(rèn)的構(gòu)造函數(shù)創(chuàng)建了一個(gè)隊(duì)列(并不知隊(duì)列是串行還是并發(fā))
// api 文檔沒(méi)有給夠足夠的信息。 后期的文檔描述完整后可以直接查看文檔。
func async() {
print("DispatchQueue(label: \"laughing\").async: befor", Thread.current)
let queue = DispatchQueue(label: "laughing")
for index in 0..<10 {
queue.async {
print("DispatchQueue(label: \"laughing\").async: task:(taskIndex:\(index)", Thread.current)
}
}
print("DispatchQueue(label: \"laughing\").async: after", Thread.current)
}
/*
這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
for index in 0..<10 {
DispatchQueue(label: "laughing").sync {
print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
}
}
*/
打?。?DispatchQueue(label: "laughing").async: befor <NSThread: 0x608000067180>{number = 1, name = main}
DispatchQueue(label: "laughing").async: after <NSThread: 0x608000067180>{number = 1, name = main}
DispatchQueue(label: "laughing").async: task:(taskIndex:0 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:1 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:2 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:3 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:4 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:5 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:6 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:7 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:8 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:9 <NSThread: 0x608000074200>{number = 3, name = (null)}
** 由于只異步執(zhí)行只開(kāi)了1 條線程, 可只。 默認(rèn)創(chuàng)建的隊(duì)列是 串行隊(duì)列**
自定義(串行)隊(duì)列同步執(zhí)行
串行隊(duì)列同步執(zhí)行,沒(méi)有開(kāi)啟線程。 代碼在主線程中執(zhí)行。
func sync() {
print("DispatchQueue(label: \"laughing\").sync: befor", Thread.current)
let queue = DispatchQueue(label: "laughing")
for index in 0..<10 {
queue.sync {
print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
}
}
/*
這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
for index in 0..<10 {
DispatchQueue(label: "laughing").sync {
print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
}
}
*/
print("DispatchQueue(label: \"laughing\").sync: after", Thread.current)
}
打?。?
DispatchQueue(label: "laughing").sync: befor <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:0) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:1) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:2) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:3) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:4) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:5) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:6) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:7) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:8) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:9) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: after <NSThread: 0x600000071d40>{number = 1, name = main}
自定義(并發(fā))隊(duì)列異步執(zhí)行
(參考全局隊(duì)列)
func async1() {
print("DispatchQueue(label: \"laughing1\").async: befor", Thread.current)
let queue = DispatchQueue(label: "laughing1", attributes: DispatchQueue.Attributes.concurrent)
for index in 0..<10 {
queue.async {
print("DispatchQueue(label: \"laughing1\").async: task:(taskIndex:\(index)", Thread.current)
}
}
print("DispatchQueue(label: \"laughing1\").async: after", Thread.current)
}
打印
DispatchQueue(label: "laughing1").async: befor <NSThread: 0x600000261d80>{number = 1, name = main}
DispatchQueue(label: "laughing1").async: after <NSThread: 0x600000261d80>{number = 1, name = main}
DispatchQueue(label: "laughing1").async: task:(taskIndex:1 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:3 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:4 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:2 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:5 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:7 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:6 <NSThread: 0x60800026da00>{number = 5, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:0 <NSThread: 0x60800026db40>{number = 6, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:8 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:9 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}
自定義(并發(fā))隊(duì)列同步執(zhí)行
func sync1() {
print("DispatchQueue(label: \"laughing1\").sync: befor", Thread.current)
let queue = DispatchQueue(label: "laughing1", attributes: DispatchQueue.Attributes.concurrent)
for index in 0..<10 {
queue.sync {
print("DispatchQueue(label: \"laughing1\").sync: task:(taskIndex:\(index))", Thread.current)
}
}
/*
這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
for index in 0..<10 {
DispatchQueue(label: "laughing").sync {
print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
}
}
*/
print("DispatchQueue(label: \"laughing1\").sync: after", Thread.current)
}
打印
DispatchQueue(label: "laughing1").sync: befor <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:0) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:1) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:2) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:3) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:4) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:5) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:6) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:7) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:8) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:9) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: after <NSThread: 0x608000061cc0>{number = 1, name = main}