簡體   English   中英

DispatchGroup 在所有離開之前通知

[英]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時,調度組是空的,因為您還沒有創建一個名為startBaseClass子類,這是進入調度組的地方。

因為你在dispatch group為空的時候調用了notify ,所以block是立刻提交的。

可能值得研究OperationQueue ,但如果您想使用您擁有的東西,您可以將notifyinit中分離出來:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM