Swift GCD

DispatchQueue 三种类型

  • Main Queue 主队列,串行
  • Global Queue 全局队列,并行
  • Custom Queue 自定义队列,默认串行
let mainQueue = DispatchQueue.main let globalQueue = DispatchQueue.global() let customSerialQueue = DispatchQueue(label: "serialQueue") let customConcurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)

GCD 线程的同步 enter - leave - notify

当我们想要在并发结束后再同步执行东西。首先我们声明一个线程组 DispatchGroup。

import Foundation let group = DispatchGroup() let queue = DispatchQueue(label: "concurrent", attributes: .concurrent) group.enter() queue.async { sleep(5) print("任务一完成") group.leave() } group.enter() queue.async { sleep(8) print("任务二完成") group.leave() } group.notify(queue: .main) { print("最后的任务") } print("Start")

直接用队列方法里的 group 参数也可以达到上面 enter() 和 leave() 的效果,但前提是闭包里执行的得是同步任务才可以。

import Foundation let group = DispatchGroup() let queue = DispatchQueue(label: "concurrent", attributes: .concurrent) queue.async(group: group, qos: DispatchQoS.default) { sleep(5) print("任务一") } queue.async(group: group, qos: DispatchQoS.default) { sleep(8) print("任务二") } group.notify(queue: .main) { print("最后的任务") } print("Start")

DispatchSemaphore

串行的执行两个异步线程

import Foundation let semaphore = DispatchSemaphore(value: 0) DispatchQueue.global().async { semaphore.wait() print("1") } DispatchQueue.global().async { sleep(2) print("2") semaphore.signal() } //打印输出为 2,1

DispatchQoS

  • userInteractive: 与用户交互相关的任务,要最重视,优先处理,保证界面最流畅
  • userInitiated: 用户主动发起的任务,要比较重视
  • default: 默认任务,正常处理即可
  • utility: 用户没有主动关注的任务
  • background: 不太重要的维护、清理等任务,有空能处理完就行
  • unspecified: 别说身份了,连身份证都没有,能处理就处理,不能处理也无所谓的

线程安全

自定义队列支持设置 flags 为 .barrier,可以支持 barrier 之前的任务全部执行完毕后,再执行 .barrier 任务,最后再执行 .barrier 之后的任务。

import Foundation // 创建一个并发队列 let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent) // 模拟一个共享资源 var sharedResource = [String]() // 读操作 func readResource() { concurrentQueue.async { print("Read operation started") let resourceCopy = sharedResource // 读取操作 print("Read operation completed: \(resourceCopy)") } } // 写操作 func writeResource(item: String) { concurrentQueue.async(flags: .barrier) { print("Write operation started") sharedResource.append(item) // 写入操作 print("Write operation completed: \(sharedResource)") } } // 模拟并发读写操作 for i in 1...5 { readResource() writeResource(item: "Item \(i)") }