之前转了一篇GCD的文章–iOS中的GCD,近日重新理解了一下GCD。
iOS中实现并行的方式有三种:操作队列(Operation Queue),调度队列(Dispatch Queue)和线程。
注意:
- Swift将GCD进行了对象化。我们可以使用DispatchQueue和DispatchGroup的实例方法操作GCD,更符合面向对象的思想。
- 文中代码在Swift4中运行良好。
- GCD(调度队列)中的核心元素有:队列、任务、调度源等等。
队列(dispatch_queue_t)
typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;
OS_dispatch_queue的定义并没有公开,猜测其中包括了对线程的相关操作。
调度队列按照先进先出的的顺序触发提交到自己的block。
- 串行队列:同时只能执行一个block。
- 并行队列:可同时触发多个block。
三种队列:
- 主队列
- 私有队列
- 全局并发队列
向队列添加任务
- dispatch_async:异步的向队列中添加任务,不知任务何时开始执行。
- dispatch_async_f:第二个参数是队列的上下文指针:unsafeBitCast(0, UnsafeMutablePointer.self)
- dispatch_sync:同步的向队列中添加任务,需要等待任务完成后才能向下执行。
- dispatch_sync_f
死锁:block等main执行完,main等block执行完
func testDeadLock() {
let q = DispatchQueue.main
print("1")
q.sync {
print("2")
}
print("3")
}
不死锁:main已释放
func testDeadLock1() {
let q = DispatchQueue.main
let gq = DispatchQueue.global()
gq.async {
print("1")
q.sync {
print("2")
}
print("3")
}
}
在队列中循环任务(swift3.2中已被废弃)
- dispatch_apply:
- dispatch_apply_f:swift3.2中已被废弃
暂定和重启任务(swift3.2中已被废弃)
- dispatch_suspend:暂停执行队列中的下一个任务。
- dispatch_resume:继续执行。
任务分组
- dispatch_group_async:将任务分为一组
dispatch_group_wait:某组任务完成后执行下面的操作
未分组:func testGroup() { var count = 0 let concurrentQueue = DispatchQueue.global() concurrentQueue.async() { print("Task1 in dispatchGroup. Current thread is \(Thread.current)") sleep(2) count += 1 } concurrentQueue.async() { print("Task2 in dispatchGroup. Current thread is \(Thread.current)") sleep(3) count += 1 } concurrentQueue.async() { print("Task3 in dispatchGroup. Current thread is \(Thread.current)") sleep(1) count += 1 } print("I expect the count is 3, and the factual count is \(count)") }
执行结果:
I expect the count is 3, and the factual count is 0
Task2 in dispatchGroup. Current thread is <NSThread: 0x604000276d80>{number = 3, name = (null)}
Task1 in dispatchGroup. Current thread is <NSThread: 0x604000276dc0>{number = 5, name = (null)}
Task3 in dispatchGroup. Current thread is <NSThread: 0x60000046dd00>{number = 4, name = (null)}
分组:
var count = 0
let concurrentQueue = DispatchQueue.global()
let dispatchGroup = DispatchGroup()
concurrentQueue.async(group: dispatchGroup) {
print("Task1 in dispatchGroup. Current thread is \(Thread.current)")
sleep(2)
count += 1
}
concurrentQueue.async(group: dispatchGroup) {
print("Task2 in dispatchGroup. Current thread is \(Thread.current)")
sleep(3)
count += 1
}
concurrentQueue.async(group: dispatchGroup) {
print("Task3 in dispatchGroup. Current thread is \(Thread.current)")
sleep(1)
count += 1
}
_ = dispatchGroup.wait(timeout: DispatchTime.distantFuture)
print("I expect the count is 3, and the factual count is \(count)")
执行结果:
Task1 in dispatchGroup. Current thread is <NSThread: 0x604000471a80>{number = 4, name = (null)}
Task2 in dispatchGroup. Current thread is <NSThread: 0x60000027ebc0>{number = 3, name = (null)}
Task3 in dispatchGroup. Current thread is <NSThread: 0x604000471c00>{number = 5, name = (null)}
I expect the count is 3, and the factual count is 3
任务
调度源(Dispatch Source)
在Swift4(3.2?)已被废弃。
参考:
1,iOS并发编程指南:Dispatch Queue任务执行与Dispatch Source
2,Apple Doc: Dispatch Queue