对循环重复调用dispatch_group_leave()的不平衡

idr*_*mer 2 concurrency dispatch ios

我正在使用调度组来获取数据字符串。这是一个代码,我不确定为什么要输入Unbalanced call to dispatch_group_leave()此代码。

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
    })
}
Run Code Online (Sandbox Code Playgroud)

San*_*ari 6

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()    
    }
})
Run Code Online (Sandbox Code Playgroud)

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() 
})
Run Code Online (Sandbox Code Playgroud)

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.