如何进行循环,直到任务完成 [英] How to make a loop wait until task is finished
问题描述
我知道该主题已经做出了很多贡献.我尝试了 DispatchGroup 的不同变体,但看来我无法使整个循环停止,直到完成某项任务为止.
I know there are a lot of contributions already for this topic. I tried different variations with DispatchGroup, but it seems I'm not able to make the whole loop stop until a certain task is finished.
let names = ["peter", "susan", "john", "peter", "susan", "john"]
var holding = [String: [Double]]()
for i in 0...10 {
for name in names {
if holding[name] == nil {
Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
// do stuff here
holding[name] = result
}
} else {
// do other stuff with existing "holding[name]"
}
// if if holding[name] == nil, the whole process should wait
}
}
如果我使用DispatchGroup,则Alamofire请求将一一执行,但是整个循环无法识别holding[name]
是否已经存在.因此holding[name]
始终为nil
,因为循环不等待.
If I´m using DispatchGroup, the Alamofire requests are executed one by one, but the the whole loop doesn't recognize if holding[name]
does already exist. So holding[name]
is always nil
because the loop doesn't wait.
非常感谢!
根据Mikes和Versus的回答,我尝试了以下操作:
According to Mikes´s and Versus´ answers, I tried the following:
var names = ["peter", "susan", "john", "peter", "susan", "john"]
var holding = [String: [Double]]()
let semaphore = DispatchSemaphore(value: 1)
for i in 0...10 {
DispatchQueue.global().async { [unowned self] in
self.semaphore.wait()
for name in names {
if holding[name] != nil {
Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
// do stuff here
holding[name] = result
semaphore.signal()
}
} else {
// do other stuff with existing "holding[name]"
semaphore.signal()
}
// if if holding[name] != nil, the wholeprocess should wait
}
}
}
但不幸的是,该应用程序崩溃了.我在做什么错了?
But unfortunately the app crashes. What am I doing wrong?
推荐答案
您在这里有两种选择
1)Semaphore
2)Operation Queues
但是在使用Semaphores
您需要注意semaphore.signal()
和semaphore.wait()
对
由于Semaphore
可能会阻塞主线程,因此所有操作都应在Dispatch.global.async
As Semaphore
may block Main Thread so all operation should be done in Dispatch.global.async
即
semaphore.wait()
Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
semaphore.signal()
holding[name] = result
}
在这里,您阻塞了主线程
问题在于完成处理程序在主线程中执行,该主线程已被最初调用的semaphore.wait()锁定.因此,当完成发生时,semaphore.signal()永远不会被调用
The problem is that the completion handler gets executed in the main thread, which was already locked by the semaphore.wait() called initially. So when the completion occurs, semaphore.signal() never gets called
您必须选择
DispatchQueue.global().async { [unowned self] in
self.semaphore.wait()
// And other statemetns
}
希望对您和其他人有帮助
Hope it is helpful to you and other
这篇关于如何进行循环,直到任务完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!