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
}
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
逻辑在应用程序中的一个级别,使您的班少紧密耦合(如地理编码器并不需要知道视图控制器是否使用派遣或不)。
坦率地说,我不清楚为什么你只使用一个调用来使用调度组。通常你会把任何你在完成处理程序中调用的内容,进一步简化代码。如果您正在进行一系列的通话,您通常只会使用群组。 (也许你只是简化了你的代码片段,而你真的在做多次调用,那么派遣组可能是有意义的,但是再一次,你不应该做并发地理代码请求,这意味着完全不同的模式,干脆。
我只想在单独的类中使用反转地理功能,并在主类中使用地标来设置属性(不调用任何回调函数)。函数1的结果是函数2所需要的,而函数3需要结果来自函数f1和f2,我使用完成处理程序来设置主类的属性。 f1将设置属性用于f2等等 –
与完成处理程序,它是否像... f1(完成:f2(完成:f3))?如果我需要f3使用f1和f2的结果 –
没有更多的上下文很难说。鉴于我们已经在这里回答了派遣组的问题,我可能会建议您在更广泛的背景下发布一个新问题,向我们展示您正在做的事情。如果您的代码可以正常工作,并且您需要关于设计的反馈,也许http://codereview.stackexchange.com是一个更好的论坛。或者如果它不工作,继续并在Stack Exchange上发布单独的问题。无论哪种方式,随意添加评论与其他问题的链接。但是我们已经偏离了原来的派遣组问题...... – Rob
传递dispatchGroup与函数调用参数和它的工作。
Geo.reverseG(coordinates, dispatchGroup, setValues)
每'leave'看涨期权必须有一个相关的'enter'电话。如果你打电话'leave',而不必首先调用'enter' ,它会崩溃,这里的问题是你在某个组中调用了'enter',但'reverseG'在'ViewController'的其他实例上调用'leave',我建议传递'DispatchGroup'作为参数指向'reverseG'方法,或者更好的是'reverseG'不应该离开组,而是将'leave'调用放入'reserveG'调用的完成处理程序中。 – Rob
确实,已经做到了这一点,它的工作。谢谢 –