我有一个iOS应用程序,它运行多个类(每个类在一个单独的线程中),我想在所有类完成运行时收到通知。
所以我有一个基类:
class BaseClass {
var completeState: CompleteState
init(completeState: CompleteState) {
self.completeState = completeState
self.completeState.dispatch.enter()
}
func start() { }
}
这就是完整状态类:
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
子类,也就是输入调度组的地方。
因为当调度组为空时调用notify
,所以块会立即提交。
研究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")
}
}