測(cè)試環(huán)境:Xcode9武福,Swift4
一.創(chuàng)建一個(gè)DispatchQueue噩翠,并為你的隊(duì)列提供一個(gè)label兔辅。建議使用反向DNS符號(hào)("com.cn.xxx")
let queue = DispatchQueue(label: "com.cn.zcy.queue")
二.串行隊(duì)列
創(chuàng)建一個(gè)串行隊(duì)列并在viewDidLoad中執(zhí)行
1.同步執(zhí)行
func execQueues() {
let queue = DispatchQueue(label: "com.cn.zcy.queue")
queue.sync {
for i in 0..<10 {
print("----", i)
}
}
for i in 10..<20 {
print("==", i)
}
}
執(zhí)行結(jié)果如圖所示数初。因?yàn)槭峭綀?zhí)行鹤啡,所以會(huì)先執(zhí)行第一個(gè)for循環(huán)肌稻,執(zhí)行完成后才會(huì)執(zhí)行第二個(gè)for循環(huán)清蚀。
2.異步執(zhí)行
修改一下代碼,改成異步執(zhí)行for循環(huán)
func execQueues() {
let queue = DispatchQueue(label: "com.cn.zcy.queue")
queue.async {
for i in 0..<10 {
print("----", i)
}
}
for i in 10..<20 {
print("==", i)
}
}
執(zhí)行結(jié)果如圖所示爹谭。因?yàn)槭钱惒綀?zhí)行枷邪,程序不會(huì)等待queue隊(duì)列的任務(wù)執(zhí)行完成,會(huì)直接回到主線程執(zhí)行第二個(gè)for循環(huán)诺凡,兩個(gè)循環(huán)同時(shí)進(jìn)行齿风。
三.Quality Of Service(QoS)
用于指定任務(wù)優(yōu)先級(jí),在 GCD 中被稱為 Quality of Service(QoS)绑洛。如果沒(méi)有指定 QoS救斑,則隊(duì)列會(huì)使用默認(rèn)優(yōu)先級(jí)進(jìn)行初始化。以下列表從高到低列出了各個(gè)優(yōu)先級(jí):
userInteractive
userInitiated
default
utility
background
unspecified
為了測(cè)試優(yōu)先級(jí)真屯,我們創(chuàng)建兩個(gè)queue脸候,并將優(yōu)先級(jí)設(shè)置為相同級(jí)別
let queue1 = DispatchQueue(label: "com.cn.zcy.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.cn.zcy.queue2", qos: DispatchQoS.userInitiated)
queue1.async {
for i in 0..<10 {
print("----", i)
}
}
queue2.async {
for i in 10..<20 {
print("==", i)
}
}
執(zhí)行結(jié)果如圖所示。因?yàn)閮?yōu)先級(jí)相同,又是異步執(zhí)行运沦,所以兩個(gè)任務(wù)被“均勻”的執(zhí)行泵额。
下面我們改變其中一個(gè)的優(yōu)先級(jí),將queue1優(yōu)先級(jí)提高
let queue1 = DispatchQueue(label: "com.cn.zcy.queue1", qos: DispatchQoS.userInteractive)
執(zhí)行結(jié)果如圖所示携添。兩個(gè)任務(wù)都獲得了執(zhí)行的機(jī)會(huì)嫁盲,但是queue1優(yōu)先級(jí)高,會(huì)優(yōu)先執(zhí)行烈掠。
現(xiàn)在羞秤,我們可以在主隊(duì)列中也執(zhí)行一個(gè)for循環(huán),來(lái)測(cè)試3個(gè)for循環(huán)的優(yōu)先級(jí)
func execQueues() {
let queue1 = DispatchQueue(label: "com.cn.zcy.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.cn.zcy.queue2", qos: DispatchQoS.default)
queue1.async {
for i in 0..<10 {
print("----", i)
}
}
queue2.async {
for i in 10..<20 {
print("==", i)
}
}
for i in 100..<110 {
print("~~~~~", i)
}
}
執(zhí)行結(jié)果如圖所示左敌●埃可以看出,主隊(duì)列最先執(zhí)行完矫限,擁有最高的優(yōu)先級(jí)哺哼。
四.并行隊(duì)列
創(chuàng)建一個(gè)并行的隊(duì)列,并加入3個(gè)任務(wù)叼风,每個(gè)任務(wù)執(zhí)行一個(gè)for循環(huán)取董,查看結(jié)果。創(chuàng)建并發(fā)隊(duì)列需要新的參數(shù)attributes无宿,并且需要設(shè)定為DispatchQueue.Attributes.concurrent
func concurrentQueue() {
let concQueue = DispatchQueue(label: "com.cn.zcy.concurrent", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent)
concQueue.async {
for i in 0..<10 {
print("----", i)
}
}
concQueue.async {
for i in 10..<20 {
print("==", i)
}
}
concQueue.async {
for i in 100..<110 {
print("~~~~", i)
}
}
}
執(zhí)行結(jié)果如圖所示甲葬。
attributes屬性也可以接受另一個(gè)值:initiallyInactive。如果使用這個(gè)值懈贺,任務(wù)不會(huì)被自動(dòng)執(zhí)行经窖,而是需要開發(fā)者手動(dòng)去觸發(fā)。
創(chuàng)建一個(gè)成員變量
var inactiveQueue: DispatchQueue!
在concQueue創(chuàng)建后賦值給inactiveQueue梭灿,并修改concQueue創(chuàng)建參數(shù)
let concQueue = DispatchQueue(label: "com.cn.zcy.concurrent", qos: DispatchQoS.default, attributes: [DispatchQueue.Attributes.concurrent, DispatchQueue.Attributes.initiallyInactive])
此時(shí)如果直接運(yùn)行并不會(huì)打印任何信息画侣。
在調(diào)用了concurrentQueue()方法后還要手動(dòng)運(yùn)行:
if let queue = inactiveQueue {
queue.activate()
}
此時(shí)會(huì)打印出信息,打印結(jié)果同上圖類似堡妒。
五.延遲執(zhí)行
創(chuàng)建一個(gè)隊(duì)列配乱,并在加入任務(wù)時(shí)延遲執(zhí)行。
func delayQueue() {
let delayQueue = DispatchQueue(label: "com.cn.delayQUeue")
print(Date())
delayQueue.asyncAfter(deadline: DispatchTime.now() + 2) {
print(Date())
}
}
執(zhí)行結(jié)果如圖所示皮迟。打印的日期之間相差了2秒搬泥。
六.主隊(duì)列與全局隊(duì)列
獲取主隊(duì)列:
let mainQueue = DispatchQueue.main
獲取全局隊(duì)列
let globalQueue = DispatchQueue.global()
使用方法同上
七. DispatchWorkItem
DispatchWorkItem 是一個(gè)代碼塊,它可以在任意一個(gè)隊(duì)列上被調(diào)用伏尼。
下面我們看看如何使用:
func useWorkItem() {
var value = 1
let workItem = DispatchWorkItem {
value += 1
}
let globalQueue = DispatchQueue.global()
globalQueue.async {
workItem.perform()
}
workItem.notify(queue: DispatchQueue.main) {
print(value)
}
}
這個(gè)workItem的作用是讓value+1忿檩,通過(guò)workItem的perform()方法來(lái)執(zhí)行代碼塊,執(zhí)行完成后可以通知主隊(duì)列爆阶。
剛開始研究Swift燥透,如有錯(cuò)誤和優(yōu)化的地方沙咏,望不吝賜教。