如何让循环等待任务完成
How to make a loop wait until task is finished
我知道这个主题已经有很多贡献。我尝试了 DispatchGroup 的不同变体,但似乎我无法让整个循环停止,直到某个任务完成。
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
因为循环不等待。
非常感谢!
编辑:
根据 Mikes 和 Versus 的回答,我尝试了以下方法:
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
}
}
}
但不幸的是应用程序崩溃了。我做错了什么?
我认为你可以使用 DispatchSemaphore 来停止循环:
let semaphore = DispatchSemaphore(value: 1)
for i in 0...10 {
for name in names {
// if signal is 0, loop will be stopped forever,
// if signal > 0, loop will continue
semaphore.wait()
if holding[name] == nil {
Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
// do stuff here
// release signal to continue current loop(signal + 1)
semaphore.signal()
holding[name] = result
}
} else {
// do other stuff with existing "holding[name]"
}
// if if holding[name] == nil, the whole process should wait
}
}
这里有两个选择
1) Semaphore
2)Operation Queues
但是在使用 Semaphores
之前你应该三思而后行
你需要谨慎对待semaphore.signal()
和semaphore.wait()
对
由于Semaphore
可能会阻塞主线程所以所有操作都应该在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() 永远不会被调用
你必须选择
DispatchQueue.global().async { [unowned self] in
self.semaphore.wait()
// And other statemetns
}
希望对你和其他人有所帮助
我知道这个主题已经有很多贡献。我尝试了 DispatchGroup 的不同变体,但似乎我无法让整个循环停止,直到某个任务完成。
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
因为循环不等待。
非常感谢!
编辑:
根据 Mikes 和 Versus 的回答,我尝试了以下方法:
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
}
}
}
但不幸的是应用程序崩溃了。我做错了什么?
我认为你可以使用 DispatchSemaphore 来停止循环:
let semaphore = DispatchSemaphore(value: 1)
for i in 0...10 {
for name in names {
// if signal is 0, loop will be stopped forever,
// if signal > 0, loop will continue
semaphore.wait()
if holding[name] == nil {
Alamofire.request("https://jsonplaceholder.typicode.com", parameters: parameters).responseJSON { responseData in
// do stuff here
// release signal to continue current loop(signal + 1)
semaphore.signal()
holding[name] = result
}
} else {
// do other stuff with existing "holding[name]"
}
// if if holding[name] == nil, the whole process should wait
}
}
这里有两个选择
1) Semaphore
2)Operation Queues
但是在使用 Semaphores
你需要谨慎对待semaphore.signal()
和semaphore.wait()
对
由于Semaphore
可能会阻塞主线程所以所有操作都应该在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() 永远不会被调用
你必须选择
DispatchQueue.global().async { [unowned self] in
self.semaphore.wait()
// And other statemetns
}
希望对你和其他人有所帮助