swift 3 DispatchGroup离开导致崩溃,当在助手类函数中调用时

问题描述:

我使用DispatchGroup.enter()和leave()来处理助手类的reverseG异步函数。问题很明显,我使用mainViewController的对象在助手类中调用mainViewControllers的dispatchGroup.leave()!有没有办法做到这一点?swift 3 DispatchGroup离开导致崩溃,当在助手类函数中调用时

当在主视图控制器中声明reverseG时,相同的代码有效。从主视图控制器

dispatchGroup.enter() 
Geo.reverseG(coordinates, setValues) // completionHandler: setValues 

dispatchGroup.notify(queue: DispatchQueue.main) { 

    // call another function on completion 

} 
+0

每'leave'看涨期权必须有一个相关的'enter'电话。如果你打电话'leave',而不必首先调用'enter' ,它会崩溃,这里的问题是你在某个组中调用了'enter',但'reverseG'在'ViewController'的其他实例上调用'leave',我建议传递'DispatchGroup'作为参数指向'reverseG'方法,或者更好的是'reverseG'不应该离开组,而是将'leave'调用放入'reserveG'调用的完成处理程序中。 – Rob

+0

确实,已经做到了这一点,它的工作。谢谢 –

class Geo { 
    var obj = ViewController() 

    static func reverseG(_ coordinates: CLLocation, _ completion: @escaping (CLPlacemark) ->()) { 
     let geoCoder = CLGeocoder() 
     geoCoder.reverseGeocodeLocation(coordinates) { (placemarks, error) in 
      if let error = error { 
       print("error: \(error.localizedDescription)") 
      } 
      if let placemarks = placemarks, placemarks.count > 0 { 
       let placemark = placemarks.first! 
       completion(placemark) // set ViewController's properties 
      } else { 
       print("no data") 
      } 
      obj.dispatchGroup.leave() // ** ERROR ** 
     } 
    } 


} 

函数调用每个leave呼叫必须有关联的呼叫enter。如果您拨打leave而未先拨打enter,则会崩溃。这里的问题是你在某个组上调用了enter,但reverseG在其他一些ViewController的实例上调用了leave。我建议将DispatchGroup作为参数传递给您的reverseG方法。或者,更好的是,reverseG不应该离开组,而是将leave调用放入reserveG调用的完成处理程序中。

dispatchGroup.enter() 
Geo.reverseG(coordinates) { placemark in 
    defer { dispatchGroup.leave() } 

    guard let placemark = placemark else { return } 

    // use placemark here, e.g. call `setValues` or whatever 
} 

dispatchGroup.notify(queue: DispatchQueue.main) { 
    // call another function on completion 
} 

而且

class Geo { 
    // var obj = ViewController() 

    static func reverseG(_ coordinates: CLLocation, completion: @escaping (CLPlacemark?) -> Void) { 
     let geoCoder = CLGeocoder() 
     geoCoder.reverseGeocodeLocation(coordinates) { placemarks, error in 
      if let error = error { 
       print("error: \(error.localizedDescription)") 
      } 
      completion(placemarks?.first) 

      // obj.dispatchGroup.leave() // ** ERROR ** 
     } 
    } 

} 

这使DispatchGroup逻辑在应用程序中的一个级别,使您的班少紧密耦合(如地理编码器并不需要知道视图控制器是否使用派遣或不)。

坦率地说,我不清楚为什么你只使用一个调用来使用调度组。通常你会把任何你在完成处理程序中调用的内容,进一步简化代码。如果您正在进行一系列的通话,您通常只会使用群组。 (也许你只是简化了你的代码片段,而你真的在做多次调用,那么派遣组可能是有意义的,但是再一次,你不应该做并发地理代码请求,这意味着完全不同的模式,干脆。

+0

我只想在单独的类中使用反转地理功能,并在主类中使用地标来设置属性(不调用任何回调函数)。函数1的结果是函数2所需要的,而函数3需要结果来自函数f1和f2,我使用完成处理程序来设置主类的属性。 f1将设置属性用于f2等等 –

+0

与完成处理程序,它是否像... f1(完成:f2(完成:f3))?如果我需要f3使用f1和f2的结果 –

+0

没有更多的上下文很难说。鉴于我们已经在这里回答了派遣组的问题,我可能会建议您在更广泛的背景下发布一个新问题,向我们展示您正在做的事情。如果您的代码可以正常工作,并且您需要关于设计的反馈,也许http://codereview.stackexchange.com是一个更好的论坛。或者如果它不工作,继续并在Stack Exchange上发布单独的问题。无论哪种方式,随意添加评论与其他问题的链接。但是我们已经偏离了原来的派遣组问题...... – Rob

传递dispatchGroup与函数调用参数和它的工作。

Geo.reverseG(coordinates, dispatchGroup, setValues)