DispatchQueue

首先,dispatch 的全局函数不再写为下划线风格的名称了,它变成了一个更符合 Swift 风格的 DispatchQueue 的样子。

main thread

同样的,你不需要在去用 dispatch_get_main_queue ( ) 来获取主线程,而是 DispatchQueue . main ,那么要放到主线程的代码怎么执行呢?只需要在线程后边使用 . async { } 即可,也就是说,大概是这样:

DispatchQueue.main.async {
    // 主线程刷新UI
}

// 或者这样
DispatchQueue.main.async { [weak self] in
    self?.image = UIImage(named: "1.png")
}

在子线程开始一个任务, 然后回到主线程刷新UI

DispatchQueue.global().async {
    // 子线程任务
    DispatchQueue.main.async {
        // 主线程刷新UI
    }
}

 优先级

说完了最基本的东西,我们再来说说其他改变了的东西,比如优先级的名字。

我们知道,GCD 的默认队列优先级有四个:

  • DISPATCH_QUEUE_PRIORITY_HIGH
  • DISPATCH_QUEUE_PRIORITY_DEFAULT
  • DISPATCH_QUEUE_PRIORITY_LOW
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND

现在,新的语法当中,改变了这四个不明不白的优先级名称为更有意义的名字:

  • .userInteractive  用户交互, 默认值33
  • .userInitialted  用户初始化, 默认值25
  • .default 默认,默认值21
  • .utility   共用,默认值17
  • .background  后台优先级,默认值9

当然,它们的对应关系大体上与顺序相同的:

DISPATCH_QUEUE_PRIORITY_HIGH:        .userInteractive DISPATCH_QUEUE_PRIORITY_DEFAULT:      .default DISPATCH_QUEUE_PRIORITY_LOW:          .utilityDISPATCH_QUEUE_PRIORITY_BACKGROUND:  .background

获取子线程队列

我们使用 DispatchQueue . global ( ) 获取一个系统的队列,这样的话获取的就是默认 . default 优先级的队列了,如果要获取其他优先级的队列,就使用 DispatchQueue. global ( qos : . userInitiated ) ,最后,我们使用 . async { } 来执行代码:

// 用户交互
DispatchQueue.global(qos: .userInteractive).async { }
// 用户初始化
DispatchQueue.global(qos: .userInitiated).async { }
// 默认
DispatchQueue.global(qos: .default).async { }
// 公共
DispatchQueue.global(qos: .utility).async { }
// 后台
DispatchQueue.global(qos: .background).async { }

创建自定义队列

直接用 DispatchQueue 的初始化器来创建一个队列。最简单直接的办法是这样:

let queue = DispatchQueue(label: "myBackgroundQueue")

复杂一点?你可以指定优先级以及队列类别:

let queue = DispatchQueue(label: "myBackgroundQueue", qos: .userInitiated, attributes: .concurrent)

然后把代码放进去即可:

queue.async {
    print("aaa")
}

延迟执行

DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: DispatchWorkItem(block: {
    print(#function,"延迟3秒执行")
}))

DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 1, execute: DispatchWorkItem(block: {
    print(#function,"延迟1秒执行")
}))

队列组

对于组,现在你可以使用这样的语法直接创建一个组:

let group = DispatchGroup()

至于使用,则是这样的:

let group = DispatchGroup()   let queue = DispatchQueue(label: "myBackgroundQueue")   queue.async(group:group) {    "background working") }

那么,如果有多个并发队列在同一个组里,我们需要它们完成了再继续呢?

let group = DispatchGroup()
let queue = DispatchQueue(label: "myBackgroundQueue")
queue.async(group:group) {
    sleep(1)
    print("子线程任务1")
}

DispatchQueue.global().async(group: group, execute: DispatchWorkItem(block: {
    sleep(3)
    print("子线程任务2")
}))

group.notify(queue: .main, work: DispatchWorkItem(block: {
    print(#function, "任务完成")
}))
// 慎用,会阻塞当前线程
// group.wait()
print(#function, "函数调用完成")

GCD信号量使用

// GCD信号量使用
let sem = DispatchSemaphore.init(value: 1)
sem.wait()
sem.signal()