簡介
Grand Central Dispatch (GCD) 是Apple開發(fā)的一個多核編程的較新的解決方法。它主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對稱多處理系統(tǒng)。
眾所周知,GCD, NSOperationQueue, NSThread, pthread是iOS中多線程的幾種處理方式,Swift3之前GCD仍是面向過程的寫法,所以需要封裝一層再使用。Swift3蘋果打成Dispatch這個module.你可以通過import進行導(dǎo)入再使用。Swift4,直接使用。
特性
GCD可用于多核的并行運算
GCD會自動利用更多的CPU內(nèi)核(比如雙核、四核)
GCD會自動管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷毀線程)
用法
- 異步執(zhí)行回主線程寫法
DispatchQueue.global().async {
print("async do something\(Thread.current)")
DispatchQueue.main.async {
print("come back to main thread\(Thread.current)")
}
}
- QoS
之前接觸過Quality of Service還是在VoIP,通過QoS來標注每個通信的priority,所以這邊其實是把
DISPATCH_QUEUE_PRIORITY_HIGHT
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND
轉(zhuǎn)換成了
User Interactive 和用戶交互相關(guān),比如動畫等等優(yōu)先級最高。比如用戶連續(xù)拖拽的計算
User Initiated 需要立刻的結(jié)果,比如push一個ViewController之前的數(shù)據(jù)計算
Utility 可以執(zhí)行很長時間,再通知用戶結(jié)果。比如下載一個文件,給用戶下載進度
Background 用戶不可見,比如在后臺存儲大量數(shù)據(jù)
在GCD中,指定QoS有以下兩種方式
方式一,創(chuàng)建一個指定QoS的queue
let queue = DispatchQueue(label: "labelname", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit)
方式二,在提交block的時候,指定QoS
queue.async(group: nil, qos: .background, flags: .inheritQoS) {
<#code#>
}
flags的參數(shù)有
public static let barrier: DispatchWorkItemFlags
public static let detached: DispatchWorkItemFlags
public static let assignCurrentContext: DispatchWorkItemFlags
public static let noQoS: DispatchWorkItemFlags
public static let inheritQoS: DispatchWorkItemFlags
public static let enforceQoS: DispatchWorkItemFlags
其中關(guān)于QoS的關(guān)系,可以通過flags參數(shù)設(shè)置。
- DispatchWorkItem
let dispatchWorkItem = DispatchWorkItem(qos: .default, flags: .barrier) {
<#code#>
}
- after
let deadline = DispatchTime.now() + 5.0
DispatchQueue.global().asyncAfter(deadline: deadline) {
<#code#>
}
- DispatchGroup
DispatchGroup用來管理一組任務(wù)的執(zhí)行,然后監(jiān)聽任務(wù)都完成的事件。比如,多個網(wǎng)絡(luò)請求同時發(fā)出去,等網(wǎng)絡(luò)請求都完成后reload UI。
let group = DispatchGroup()
group.enter()
self.sendHTTPRequest1(params:[String: Any]) {
print("request complete")
group.leave()
}
group.enter()
self.sendHTTPRequest1(params:[String: Any]) {
print("request complete")
group.leave()
}
group.notify(queue: DispatchQueue.main) {
print("all requests come back")
}
- Semaphore
Semaphore是保證線程安全的一種方式,而且繼OSSpinLock不再安全后,Semaphore似乎成為了最快的加鎖的方式。
如圖

let semaphore = DispatchSemaphore(value: 2)
let queue = DispatchQueue.global()
queue.async {
semaphore.wait()
self.sendHTTPRequest1(params:[String: Any]) {
print("request complete")
semaphore.signal()
}
}
queue.async {
semaphore.wait()
self.sendHTTPRequest2(params:[String: Any]) {
print("request complete")
semaphore.signal()
}
}
queue.async {
semaphore.wait()
self.sendHTTPRequest3(params:[String: Any]) {
print("request complete")
semaphore.signal()
}
}
- Barrier
GCD里的Barrier和NSOperationQueue的dependency比較接近,C任務(wù)開始之前需要A任務(wù)完成,或者A和B任務(wù)完成。
let queue = DispatchQueue(label: "foo", attributes: .concurrent)
queue.async {
self.sendHTTPRequest1(params:[String: Any]) {
print("A")
}
}
queue.async {
self.sendHTTPRequest2(params:[String: Any]) {
print("B")
}
}
queue.async(flags: .barrier) {
self.sendHTTPRequest3(params:[String: Any]) {
print("C")
}
}