DispatchGroup 中的几个任务。他们会 运行 有序吗?
Several tasks inside a DispatchGroup. Will they run in order?
在下面的代码中,附加到数组是否安全?订单保证能维持吗?
let processedData: [SomeType] = []
let dispatchGroup = DispatchGroup()
for _ in 0..<N {
dispatchGroup.enter()
startSomeAsyncTaskXYZ { (data, error) in
// handle error and process data
// add processed data to an array
processedData.append(..)
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main) {
// update UI
}
DispatchGroup
与执行顺序无关。它只是一种跟踪任务组完成情况的方法。
小组的组成任务是运行async
还是sync
,以及顺序如何,完全取决于您如何使用DispatchQueue
s。
要坚持 DispatchGroup
同时保留所需的异步性质和预期的顺序,请将您的数组设为可选数组,并按照任务完成的顺序填充它:
var processedData: [SomeType?] = Array(repeating: nil, count: N)
let dispatchGroup = DispatchGroup()
for idx in 0..<N {
dispatchGroup.enter()
startSomeAsyncTaskXYZ { (data, error) in
// Ensure we always .leave() after we're done
// handling the completion of the task
defer { dispatchGroup.leave() }
guard let data = data,
error == nil else {
// TODO: Actual error handling
return
}
// This needs to be .sync now (not .async) to ensure
// the deferred dispatchGroup.leave() is not called
// until *after* we've updated the array
DispatchQueue.main.sync {
processedData[idx] = SomeType(data: data)
}
}
}
dispatchGroup.notify(queue: .main) {
// update UI
}
刚刚用我的应用程序完成了这个。我有一些需要按顺序完成的异步任务。实现这一目标的最佳方法是通过 dispatchGroup()
和 semaphore()
.
基本思想是 dispatchGroup
不按特定顺序获取数据,但 semaphore
在需要时按特定顺序获取数据。
这是一个很好的演示视频:https://www.youtube.com/watch?v=6rJN_ECd1XM&ab_channel=LetsBuildThatApp
一些示例代码如下所示:
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
let dispatchGroup = DispatchGroup()
let semaphore = DispatchSemaphore(value: 0)
override func viewDidLoad() {
dispatchQueue.async {
// --------------
// Family members
// --------------
// Get members and household information first (esp. payday time and time zone), then everything else
self.dispatchGroup.enter()
MPUser.loadFamilyMembers {
print("We got us some fambly members!")
self.dispatchGroup.leave()
self.semaphore.signal()
}
// ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first)
self.semaphore.wait()
// --------------
// Household info
// --------------
self.dispatchGroup.enter()
FamilyData.observeHouseholdInformation {
self.dispatchGroup.leave()
self.semaphore.signal()
}
// ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first, then household info)
self.semaphore.wait()
// ---------------
// Everything else
// ---------------
self.dispatchGroup.enter()
Setup.observeProgress {
self.dispatchGroup.leave()
}
self.dispatchGroup.enter()
OutsideIncome.observeUserOutsideIncomeBudget {
self.dispatchGroup.leave()
}
self.dispatchGroup.enter()
MPUser.observeCurrentEarnings {
self.dispatchGroup.leave()
}
self.dispatchGroup.notify(queue: .main) {
let end = Date()
print("\nAll functions completed in \(end.timeIntervalSince(self.start!).rounded(toPlaces: 2)) seconds!\n")
self.sendUserToCorrectPage()
}
}
}
在下面的代码中,附加到数组是否安全?订单保证能维持吗?
let processedData: [SomeType] = []
let dispatchGroup = DispatchGroup()
for _ in 0..<N {
dispatchGroup.enter()
startSomeAsyncTaskXYZ { (data, error) in
// handle error and process data
// add processed data to an array
processedData.append(..)
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main) {
// update UI
}
DispatchGroup
与执行顺序无关。它只是一种跟踪任务组完成情况的方法。
小组的组成任务是运行async
还是sync
,以及顺序如何,完全取决于您如何使用DispatchQueue
s。
要坚持 DispatchGroup
同时保留所需的异步性质和预期的顺序,请将您的数组设为可选数组,并按照任务完成的顺序填充它:
var processedData: [SomeType?] = Array(repeating: nil, count: N)
let dispatchGroup = DispatchGroup()
for idx in 0..<N {
dispatchGroup.enter()
startSomeAsyncTaskXYZ { (data, error) in
// Ensure we always .leave() after we're done
// handling the completion of the task
defer { dispatchGroup.leave() }
guard let data = data,
error == nil else {
// TODO: Actual error handling
return
}
// This needs to be .sync now (not .async) to ensure
// the deferred dispatchGroup.leave() is not called
// until *after* we've updated the array
DispatchQueue.main.sync {
processedData[idx] = SomeType(data: data)
}
}
}
dispatchGroup.notify(queue: .main) {
// update UI
}
刚刚用我的应用程序完成了这个。我有一些需要按顺序完成的异步任务。实现这一目标的最佳方法是通过 dispatchGroup()
和 semaphore()
.
基本思想是 dispatchGroup
不按特定顺序获取数据,但 semaphore
在需要时按特定顺序获取数据。
这是一个很好的演示视频:https://www.youtube.com/watch?v=6rJN_ECd1XM&ab_channel=LetsBuildThatApp
一些示例代码如下所示:
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
let dispatchGroup = DispatchGroup()
let semaphore = DispatchSemaphore(value: 0)
override func viewDidLoad() {
dispatchQueue.async {
// --------------
// Family members
// --------------
// Get members and household information first (esp. payday time and time zone), then everything else
self.dispatchGroup.enter()
MPUser.loadFamilyMembers {
print("We got us some fambly members!")
self.dispatchGroup.leave()
self.semaphore.signal()
}
// ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first)
self.semaphore.wait()
// --------------
// Household info
// --------------
self.dispatchGroup.enter()
FamilyData.observeHouseholdInformation {
self.dispatchGroup.leave()
self.semaphore.signal()
}
// ^^^ Wait for above code to finish ('signal') before moving on (in other words, get users first, then household info)
self.semaphore.wait()
// ---------------
// Everything else
// ---------------
self.dispatchGroup.enter()
Setup.observeProgress {
self.dispatchGroup.leave()
}
self.dispatchGroup.enter()
OutsideIncome.observeUserOutsideIncomeBudget {
self.dispatchGroup.leave()
}
self.dispatchGroup.enter()
MPUser.observeCurrentEarnings {
self.dispatchGroup.leave()
}
self.dispatchGroup.notify(queue: .main) {
let end = Date()
print("\nAll functions completed in \(end.timeIntervalSince(self.start!).rounded(toPlaces: 2)) seconds!\n")
self.sendUserToCorrectPage()
}
}
}