I am using dispatch group to get a data string. Here is a code and I am not sure why I get Unbalanced call to dispatch_group_leave()
in this code.
var queue = DispatchQueue(label: "extractStringQueue", attributes: .concurrent)
queue.async {
let m_group = DispatchGroup()
let weeks = self.weekDataArray
for week in weeks {
for day in week.dayDataArray {
m_group.enter()
day.processStringData(dataName, completionHandler: { (data, response, error) in
if true {
// Process
m_group.leave()
}
})
}
}
m_group.notify(queue: queue, execute: {
// CompletionHandler
})
}
Two possible issues :
Issue 1:
processStringData
function might be calling its completionHandler
more than once hence resulting in multiple m_group.leave()
call. Number of m_group.leave()
should always be equal to m_group.enter()
. If you try to m_group.leave()
more number of times then u entered the group u'll receive this error.
Issue 2:
m_group.enter()
day.processStringData(dataName, completionHandler: { (data, response, error) in
if true {
// Process
m_group.leave()
}
})
Your code says only if completionHandler returns true leave the group so if it returns false u'll never leave the group. This will cause m_group.notify
never to trigger even if once the completion block returns false and unnecessarily blocks the thread forever.
What u should do rather is
m_group.enter()
day.processStringData(dataName, completionHandler: { (data, response, error) in
if true {
// Process
}
m_group.leave()
})
Issue 3:
Make sure processStringData is not changing the thread before executing the completion block. Its a common practice to switch back to main thread and execute the completion block. Entering to dispatch_group
using different thread and trying to leave the group from completely different thread will also cause unbalanced call to leave.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With