本文不涉及 GCD 的概念和理论,仅记录了 GCD 在一些开发场景下的应用。 欢迎大家积极留言补充。
耗时操作
这是应用最广泛的场景,为了避免阻塞主线程,将耗时操作放在子线程处理,然后在主线程使用处理结果。比如读取沙盒中的一些数据,然后将读取的数据展示在 UI,这个场景还有几个细分:
执行一个耗时操作后回调主线程
// 主线程需要子线程的处理结果
func handle<T>(somethingLong: @escaping () -> T, finshed: @escaping (T) -> ()) {
globalQueue.async {
let data = somethingLong()
self.mainQueue.async {
finshed(data)
}
}
}
// 主线程不需要子线程的处理结果
func handle(somethingLong: @escaping () -> (), finshed: @escaping () -> ()) {
let workItem = DispatchWorkItem {
somethingLong()
}
globalQueue.async(execute: workItem)
workItem.wait()
finshed()
}
=========================================================================
GCDKit().handle(somethingLong: { [weak self] in
self?.color = UIColor.red
sleep(2)
}) { [weak self] in
self?.view.backgroundColor = self?.color
}
GCDKit().handle(somethingLong: {
let p = Person()
p.age = 40
print(Date(), p.age)
sleep(2)
return p
}) { (p: Person) in
print(Date(), p.age)
}
串行耗时操作
每一段子任务依赖上一个任务完成,全部完成后回调主线程:
// 向全局并发队列添加任务,添加的任务会同步执行
func wait(code: @escaping GCDKitHandleBlock) -> GCDKit {
handleBlockArr.append(code)
return self
}
// 处理完毕的回调,在主线程异步执行
func finshed(code: @escaping GCDKitHandleBlock) {
globalQueue.async {
for workItem in self.handleBlockArr {
workItem()
}
self.handleBlockArr.removeAll()
self.mainQueue.async {
code()
}
}
}
=======================================================================
GCDKit().wait {
self.num += 1
}.wait {
self.num += 2
}.wait {
self.num += 3
}.wait {
self.num += 4
}.wait {
self.num += 5
}.finshed {
print(self.num, Thread.current)
}
并发耗时操作
每一段子任务独立,所有子任务完成后回调主线程:
// 向自定义并发队列添加任务,添加的任务会并发执行
func handle(code: @escaping GCDKitHandleBlock) -> GCDKit {
let queue = DispatchQueue(label: "", attributes: .concurrent)
let workItem = DispatchWorkItem {
code()
}
queue.async(group: group, execute: workItem)
return self
}
// 此任务执行时会排斥其他的并发任务,一般用于写入事务,保证线程安全。
func barrierHandle(code: @escaping GCDKitHandleBlock) -> GCDKit {
let queue = DispatchQueue(label: "", attributes: .concurrent)
let workItem = DispatchWorkItem(flags: .barrier) {
code()
}
queue.async(group: group, execute: workItem)
return self
}
// 处理完毕的回调,在主线程异步执行
func allDone(code: @escaping GCDKitHandleBlock) {
group.notify(queue: .main, execute: {
code()
})
}
======================================================================
GCDKit().barrierHandle {
self.num += 1
}.barrierHandle {
self.num += 2
}.barrierHandle {
self.num += 3
}.handle {
self.num += 4
}.handle {
self.num += 5
}.allDone {
self.num += 6
print(self.num, T