gpt4 book ai didi

swift - 如何使用 Dispatch Groups 等待调用依赖于不同数据的多个函数?

转载 作者:可可西里 更新时间:2023-11-01 00:39:11 25 4
gpt4 key购买 nike

我有三个变量,abc。我有三个带有完成 block 的异步函数来更新这些变量,还有另外三个函数只处理一些数据。

我确保工作函数一直等到所有数据都用 DispatchGroup 更新。

// The Data
var a: String?
var b: String?
var c: String?

// The Update
let group = DispatchGroup()

group.enter()
updateA() {
group.leave()
}

group.enter()
updateB() {
group.leave()
}

group.enter()
updateC() {
group.leave()
}

group.wait()

// The work
doSomthingWith(a: a, b: b)
doSomethingElseWith(b: b, c: c)
doAnotherThingWith(a: a, c: c)

我希望能够做的是在参数更新后调用每个工作函数,而不是等待一切。这只是一个(显然)简化的版本。可能有更多的变量和函数。

我正在使用 Swift。非常感谢。

最佳答案

要单独使用调度组实现这一点,您需要三个相应地进入和离开的调度组:

let abGroup = DispatchGroup()
let bcGroup = DispatchGroup()
let acGroup = DispatchGroup()

abGroup.enter()
abGroup.enter()
bcGroup.enter()
bcGroup.enter()
acGroup.enter()
acGroup.enter()

// When a is updated:
abGroup.leave()
acGroup.leave()

// When b is updated:
abGroup.leave()
bcGroup.leave()

// When c is updated:
acGroup.leave()
bcGroup.leave()

然后就可以独立等待每组完成了

abGroup.notify(queue: .main) {
// Do something with a and b
}
bcGroup.notify(queue: .main) {
// Do something with b and c
}
acGroup.notify(queue: .main) {
// Do something with a and c
}

但是,这不能很好地扩展更多任务和依赖项。

更好的方法是添加 Operation到一个 OperationQueue ,允许添加任意依赖项:

let queue = OperationQueue()

let updateA = BlockOperation {
// ...
}
queue.addOperation(updateA)

let updateB = BlockOperation {
// ...
}
queue.addOperation(updateB)

let updateC = BlockOperation {
// ...
}
queue.addOperation(updateC)

let doSomethingWithAandB = BlockOperation {
// ...
}
doSomethingWithAandB.addDependency(updateA)
doSomethingWithAandB.addDependency(updateB)
queue.addOperation(doSomethingWithAandB)

let doSomethingWithBandC = BlockOperation {
// ...
}
doSomethingWithBandC.addDependency(updateB)
doSomethingWithBandC.addDependency(updateC)
queue.addOperation(doSomethingWithBandC)

let doSomethingWithAandC = BlockOperation {
// ...
}
doSomethingWithAandC.addDependency(updateA)
doSomethingWithAandC.addDependency(updateC)
queue.addOperation(doSomethingWithAandC)

对于带有完成处理程序的异步请求,您可以使用(local) dispatch group inside each block operation 等待完成。

这是一个独立的例子:

import Foundation

var a: String?
var b: String?
var c: String?

let queue = OperationQueue()

let updateA = BlockOperation {
let group = DispatchGroup()
group.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0, execute: {
a = "A"
group.leave()
})
group.wait()
print("updateA done")
}
queue.addOperation(updateA)

let updateB = BlockOperation {
let group = DispatchGroup()
group.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 2.0, execute: {
b = "B"
group.leave()
})
group.wait()
print("updateB done")
}
queue.addOperation(updateB)

let updateC = BlockOperation {
let group = DispatchGroup()
group.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 3.0, execute: {
c = "C"
group.leave()
})
group.wait()
print("updateC done")
}
queue.addOperation(updateC)

let doSomethingWithAandB = BlockOperation {
print("a=", a!, "b=", b!)
}
doSomethingWithAandB.addDependency(updateA)
doSomethingWithAandB.addDependency(updateB)
queue.addOperation(doSomethingWithAandB)

let doSomethingWithAandC = BlockOperation {
print("a=", a!, "c=", c!)
}
doSomethingWithAandC.addDependency(updateA)
doSomethingWithAandC.addDependency(updateC)
queue.addOperation(doSomethingWithAandC)

let doSomethingWithBandC = BlockOperation {
print("b=", b!, "c=", c!)
}
doSomethingWithBandC.addDependency(updateB)
doSomethingWithBandC.addDependency(updateC)
queue.addOperation(doSomethingWithBandC)

queue.waitUntilAllOperationsAreFinished()

输出:

updateA doneupdateB donea= A b= BupdateC donea= A c= Cb= B c= C

关于swift - 如何使用 Dispatch Groups 等待调用依赖于不同数据的多个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50026983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com