简体   繁体   English

DispatchGroup 在所有离开之前通知

[英]DispatchGroup notify before all leave called

I have an iOS application that runs multiple classes(every class in a separate thread) and I want to get a notification when all the class finishes their run.我有一个运行多个类的 iOS 应用程序(每个类都在一个单独的线程中),我想在所有类完成运行时收到通知。

So I have a BaseClass:所以我有一个基类:

class BaseClass {
    var completeState: CompleteState
    
    init(completeState: CompleteState) {
        self.completeState = completeState
        self.completeState.dispatch.enter()
    }
    
    func start() { }
}

And this is the CompleteState Class:这是 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")
        }
    }
}

And I have multiple classes that inherit from BaseClass , and all of them are in this form:我有多个继承自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()
        }
    }
}

This is the code that runs all of this:这是运行所有这些的代码:

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()
        }
    }
}

And the problem is that I get dispatch.notify called before all the classes finish their work, any idea what is the problem?问题是在所有类完成工作之前我得到了dispatch.notify调用,知道是什么问题吗?

The documentation for notify states: notify状态的文档

This function schedules a notification block to be submitted to the specified queue when all blocks associated with the dispatch group have completed.当与调度组关联的所有块都完成时,此函数安排一个通知块提交到指定队列。 If the group is empty (no block objects are associated with the dispatch group), the notification block object is submitted immediately.如果该组为空(没有块对象与调度组相关联),则立即提交通知块对象。 When the notification block is submitted, the group is empty.提交通知块时,该组为空。

You are calling dispatch.notify() in your CompleteState init .您在CompleteState init中调用dispatch.notify() At the time you are calling notify , the dispatch group is empty, because you haven't yet created a BaseClass subclass let along called start , which is where the dispatch group is entered.在您调用notify时,调度组是空的,因为您还没有创建一个名为startBaseClass子类,这是进入调度组的地方。

Because you call notify when the dispatch group is empty, the block is submitted immediately.因为你在dispatch group为空的时候调用了notify ,所以block是立刻提交的。

It may be worth looking into OperationQueue , but if you want to use what you have you can split the notify out from the init :可能值得研究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)
    }
}

You would then provide the completion block after you call startClasses然后,您将在调用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.

相关问题 立即调用 DispatchGroup notify() - 不等待进入/离开 - DispatchGroup notify() called immediately - not waiting for Enter/Leave Swift DispatchGroup 在任务完成前通知 - Swift DispatchGroup notify before task finish 在完成所有任务之前调用dispatch_group_notify - dispatch_group_notify is called before all tasks are done 为什么在第一个任务退出后调用 dispatchGroup.notify ? - Why is dispatchGroup.notify called after only the first task has exited? dispatch_group_notify被调用的次数与在嵌套块中调用dispatch_group_leave的次数相同 - dispatch_group_notify being called as many times as dispatch_group_leave is called in nested blocks 在任务完成之前调用 Dispatch.notify? - Dispatch.notify being called before task has completed? 仅在两次调用方法时,DispatchGroup才会退出 - DispatchGroup will only exit when method is called twice 在 DispatchGroup 完成之前关闭 vc 会导致应用程序崩溃吗? - Will dismissing a vc before a DispatchGroup finishes crash the app? 在获取异步数据时,在获取所需结果之前,提前调用通知块。希望在获取所有数据后重新加载 collectionView - While fetching async data, notify block gets called early, before getting the required results.Want to reload collectionView after all data fetched dispatch_group_notify已被实例方法DispatchGroup.notify取代(qos:flags:queue:execute :) - dispatch_group_notify has been replaced by instance method DispatchGroup.notify(qos:flags:queue:execute:)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM