在开发过程中,都会同服务器进行交互,获取数据上传资源等。
在并发请求时,往往都只需要最终的一个结果。
比如,request请求 A,和请求 B, 我只需要知道最终 A 和 B 的执行结果。
- 第一种办法
用DispatchGroup
、leave()
和enter()
方法,
let group = DispatchGroup()
在开始请求 A 时,group.enter()
使信号量+1,在回调结果中group.leave()
-1,当最终信号量平衡为0
时,会执行group.notify(queue: DispatchQueue.global()) {}
中的 block,但是,请注意,如果 leave 和 enter不守恒,会造成内存泄漏
。
代码如下
for request in netWorkRequests {
DispatchQueue.global().async(group: group, execute: {
group.enter() //+1
//模拟网络请求回调 block,因为网络请求也是会异步请求
DispatchQueue.global().async(execute: {
group.leave() //-1
})
print("\(Date()) --> 结束 %d==%@",image, Thread.current)
})
}
group.notify(queue: DispatchQueue.global()) {
print("\(Date()) --> 任务完成通知任务组")
}
这种做法简单,只需要 enter、leave 就可以了,但是这样的弊端就是:
一旦没有执行到 group.leave ,没有-1,那么通知永远也不会执行到,也就会造成内存泄漏
。
- 第二种办法
信号量DispatchSemaphore
let group = DispatchGroup()
let semaphore = DispatchSemaphore(value: 0)
for request in netWorkRequests {
DispatchQueue.global().async(group: group, execute: {
group.enter() //+1
//模拟网络请求回调 block,因为网络请求也是会异步请求
DispatchQueue.global().async(execute: {
group.leave() //-1
})
print("\(Date()) --> 结束 %d==%@",image, Thread.current)
})
}
group.notify(queue: DispatchQueue.global()) {
print("\(Date()) --> 任务完成通知任务组")
}
//并发执行之后通知结果
group.notify(queue: DispatchQueue.global()) {
for (i, _) in images.enumerated() where i>0{
semaphore.wait(timeout: DispatchTime.now()+DispatchTimeInterval.seconds(2*(images.count-(i+1))))
}
print("\(Date()) --> 任务完成通知任务组")
}
//如果信号量为0,则等待执行 semaphore.signal(),如果在 timeout 时间范围内没有 signal,依然会继续执行接下来的代码
semaphore.wait(timeout: DispatchTime.now()+DispatchTimeInterval.seconds(2*images.count))