Во-первых, вы правы, DispatchGroup
действительно поточно-ориентирован. Это не проблема.
Вы получаете эту ошибку «Несбалансированный вызов», если вы leave
больше раз, чем вы enter
.
Итак, одна или несколько из этих четырех подпрограмм, getData1
, processData1
, getData2
или processData2
должны вызывать соответствующий обработчик завершения более одного раза. В этом сценарии для одного звонка enter
у вас есть более одного звонка leave
.
Нам понадобятся эти подпрограммы getData
и processData
для дальнейшей диагностики, но я подозреваю, что Вы сможете найти его.
Вы сказали:
Я дважды проверил, что любые дополнения (и вложенные) не вызываются дважды, что может привести к дополнительный звонок в группу отправки.
Тем не менее, это должно быть проблемой. Я бы предложил проверить это эмпирически, возможно, временно добавив операторы журналирования и, возможно, логический тест, например:
func updateHealthKitData(from startDate: Date, to endDate: Date, completion: @escaping () -> ()) {
let group = DispatchGroup()
group.enter()
var hasRunAlready1 = false
self.hkDataStore.getData1(startDate: startDate, endDate: endDate, completion: {(data1) in
if let samplesToProcess = data1 {
self.processData1(data: samplesToProcess, completion: {() in
if hasRunAlready1 { fatalError("Has run 1 already - a") }
hasRunAlready1 = true
print("1a")
group.leave()
})
} else {
if hasRunAlready1 { fatalError("Has run 1 already - b") }
hasRunAlready1 = true
print("1b")
group.leave()
}
})
group.enter()
var hasRunAlready2 = false
self.hkDataStore.getData2(startDate: startDate, completion: {(data2) in
if let samplesToProcess = data2 {
self.processData2(data: samplesToProcess, completion: {() in
if hasRunAlready2 { fatalError("Has run 2 already - a") }
hasRunAlready2 = true
print("2a")
group.leave()
})
} else {
if hasRunAlready2 { fatalError("Has run 2 already - b") }
hasRunAlready2 = true
print("2b")
group.leave()
}
})
group.notify(queue: .main) {
completion()
}
}