今天项目碰到一个网络请求的多线程问题, 为了解决这个问题,翻阅大量文章,最终得到答案,仅以此记录,方便后期回顾和日后再用。
首先阐述下我遇到的问题,是要上传两张图片到亚马逊,两张上传成功后再请求自己服务器获取合成图片。由于要求图片上传失败即弹出提示重试或者取消的alert,所以在我前期的版本遇到了弹出两次的异常问题。代码如下:
1. //创建group
group=DispatchGroup()
group.enter()
uploadParentsPhoto(s3Info: temp.motherS3!.imageInfo)
group.enter()
uploadParentsPhoto(s3Info: temp.fatherS3!.imageInfo)
group.notify(queue: .main, work:DispatchWorkItem(block: {
self.requestForBabyForecast(fatherS3: temp.fatherS3!, motherS3: temp.motherS3!)
}))
2.
private func uploadParentsPhoto(s3Info:LES3ImageInfo){
LEAWSServiceManager.shared().upload(data: s3Info.image.pngData() ??Data(), key: s3Info.key, uploadProgressBlock: { (progress)in
}) {[weakself] (sucess,error)in
ifsucess
{
self?.group.leave()
}
else
{
//失败的请求
ifleterror:NSError= errorasNSError?,error.code==-999
{
return
}
//失败弹窗
self?.alertVC(sureHandler: {[weakself]in
//do something
})
}
}
}
下面是我在demo上做的一个修改后的逻辑
@objc private func buttonClick()
{
// let opera1 = BlockOperation {
// self.request(para: 1) {
//
// }
// }
//
// let opera2 = BlockOperation {
// self.request(para: 2) {
//
// }
// }
//
// let opera3 = BlockOperation {
// self.request(para: 3) {
//
// }
// }
//
// opera2.addDependency(opera1)
// opera3.addDependency(opera2)
// OperationQueue.main.addOperations([opera1,opera2,opera3], waitUntilFinished: false)
letgroup =DispatchGroup()
group.enter()
letsampore =DispatchSemaphore(value:0)
request(para:1,completion: {
group.leave()
sampore.signal()
})
_= sampore.wait(timeout: .distantFuture)
group.enter()
request(para:2) {
group.leave()
sampore.signal()
}
_= sampore.wait(timeout: .distantFuture)
group.enter()
request(para:3) {
group.leave()
sampore.signal()
}
_= sampore.wait(timeout: .distantFuture)
group.notify(queue: .main, work:DispatchWorkItem(block: {
print("do all finish work")
}))
}
privatefuncrequest(para:Int,completion:@escaping(()->()))
{
let path ="http://www.jianshu.com/p/6930f335adba"
lettask =URLSession.shared.dataTask(with:URLRequest(url:URL(string: path)!)) { (data, reponse, error)in
print("request-\(para):finish")
completion()
}
task.resume()
}
打印结果为:
然后我来解释下我个人对这个问题的解决后的理解:
首先group常常用来处理分组的并发异步事件比较好,而信号量让这些异步的网络请求顺序执行,即a执行完了再去执行b,ab都执行完了,再去执行终极任务c。
以上是个人理解,可能有偏差,有问题可以@我 lgfprivate@sina.com