[英]DispatchGroup notify() called immediately - not waiting for Enter/Leave
[英]DispatchGroup notify before all leave called
我有一個運行多個類的 iOS 應用程序(每個類都在一個單獨的線程中),我想在所有類完成運行時收到通知。
所以我有一個基類:
class BaseClass {
var completeState: CompleteState
init(completeState: CompleteState) {
self.completeState = completeState
self.completeState.dispatch.enter()
}
func start() { }
}
這是 CompleteState 類:
class CompleteState {
let userId:String
let dispatch = DispatchGroup()
init(userId:String) {
self.userId = userId
dispatch.notify(queue: DispatchQueue.main) {
print("Finish load all data")
}
}
}
我有多個繼承自BaseClass
的類,它們都是這種形式:
class ExampleClass1: BaseClass {
override func start() {
DispatchQueue.global().async {
print("ExampleClass1 - Start running")
//DOING SOME CALCULATIONS
print("ExampleClass1 - Finish running")
self.completeState.dispatch.leave()
}
}
}
這是運行所有這些的代碼:
public class RunAll {
let completeState: CompleteState
let classArray: [BaseClass]
public init(userId: String) {
self.completeState = CompleteState(userId: userId)
classArray = [ExampleClass1(completeState: completeState),
ExampleClass2(completeState: completeState),
ExampleClass3(completeState: completeState),
ExampleClass4(completeState: completeState),
ExampleClass5(completeState: completeState),
ExampleClass6(completeState: completeState),
ExampleClass7(completeState: completeState),
ExampleClass8(completeState: completeState),
ExampleClass9(completeState: completeState)]
startClasses()
}
private func startClasses() {
for foo in classArray {
foo.start()
}
}
}
問題是在所有類完成工作之前我得到了dispatch.notify
調用,知道是什么問題嗎?
notify
狀態的文檔:
當與調度組關聯的所有塊都完成時,此函數安排一個通知塊提交到指定隊列。 如果該組為空(沒有塊對象與調度組相關聯),則立即提交通知塊對象。 提交通知塊時,該組為空。
您在CompleteState
init
中調用dispatch.notify()
。 在您調用notify
時,調度組是空的,因為您還沒有創建一個名為start
的BaseClass
子類,這是進入調度組的地方。
因為你在dispatch group為空的時候調用了notify
,所以block是立刻提交的。
可能值得研究OperationQueue
,但如果您想使用您擁有的東西,您可以將notify
從init
中分離出來:
lass CompleteState {
let userId:String
let dispatch = DispatchGroup()
init(userId:String) {
self.userId = userId
}
func registerCompletionBlock(handler: @escaping () -> Void) {
self.dispatch.notify(queue: DispatchQueue.main, execute: handler)
}
}
然后,您將在調用startClasses
后提供完成塊
public init(userId: String) {
self.completeState = CompleteState(userId: userId)
classArray = [ExampleClass1(completeState: completeState),
ExampleClass2(completeState: completeState),
ExampleClass3(completeState: completeState),
ExampleClass4(completeState: completeState),
ExampleClass5(completeState: completeState),
ExampleClass6(completeState: completeState),
ExampleClass7(completeState: completeState),
ExampleClass8(completeState: completeState),
ExampleClass9(completeState: completeState)]
startClasses()
self.completeState.registerCompletionBlockHandler {
print("Finish load all data")
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.