I'm using DispatchGroup.enter() and leave() to process a helper class's reverseG async function. Problem is clear, I'm using mainViewController's object to call mainViewControllers's dispatchGroup.leave() in helper class! Is there a way to do it?
我正在使用DispatchGroup.enter()和leave()来处理helper类的reverseG异步函数。问题很明显,我正在使用mainViewController的对象来调用mainViewControllers的dispatchGroup.leave()在helper类中!有办法吗?
Same code works when reverseG is declared in the main view controller.
当在主视图控制器中声明reverseG时,同样的代码可以工作。
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 **
}
}
}
Function call from main view controller
从主视图控制器调用函数
dispatchGroup.enter()
Geo.reverseG(coordinates, setValues) // completionHandler: setValues
dispatchGroup.notify(queue: DispatchQueue.main) {
// call another function on completion
}
2 个解决方案
#1
1
Every leave
call must have an associated enter
call. If you call leave
without having first called enter
, it will crash. The issue here is that you're calling enter
on some group, but reverseG
is calling leave
on some other instance of ViewController
. I'd suggest passing the DispatchGroup
as a parameter to your reverseG
method. Or, better, reverseG
shouldn't leave the group, but rather put the leave
call inside the completion handler that reserveG
calls.
每个请假电话必须有一个相关的输入呼叫。如果你没有先调用enter就调用leave,它会崩溃。这里的问题是你调用某个组的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
}
And
和
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 **
}
}
}
This keeps the DispatchGroup
logic at one level of the app, keeping your classes less tightly coupled (e.g. the Geo coder doesn't need to know whether the view controller uses dispatch groups or not).
这将使DispatchGroup逻辑保持在应用程序的一个级别,减少类的紧密耦合(例如,Geo编码器不需要知道视图控制器是否使用分派组)。
Frankly, I'm not clear why you're using dispatch group at all if there's only one call. Usually you'd put whatever you call inside the completion handler, simplifying the code further. You generally only use groups if you're doing a whole series of calls. (Perhaps you've just simplified your code snippet whereas you're really doing multiple calls. In that case, a dispatch group might make sense. But then again, you shouldn't be doing concurrent geocode requests, suggesting a completely different pattern, altogether.
坦白地说,我不清楚如果只有一个调用,为什么还要使用dispatch group。通常,您将调用的任何内容放入完成处理程序中,从而进一步简化代码。通常只在执行一系列调用时才使用组。(也许您只是简化了代码片段,而实际上您正在执行多个调用。在这种情况下,分派组可能是有意义的。但话说回来,您不应该执行并发的地理代码请求,这意味着完全不同的模式。
#2
0
Passed dispatchGroup as parameter with function call and it worked.
通过函数调用将dispatchGroup作为参数传递,并正常工作。
Geo.reverseG(coordinates, dispatchGroup, setValues)
#1
1
Every leave
call must have an associated enter
call. If you call leave
without having first called enter
, it will crash. The issue here is that you're calling enter
on some group, but reverseG
is calling leave
on some other instance of ViewController
. I'd suggest passing the DispatchGroup
as a parameter to your reverseG
method. Or, better, reverseG
shouldn't leave the group, but rather put the leave
call inside the completion handler that reserveG
calls.
每个请假电话必须有一个相关的输入呼叫。如果你没有先调用enter就调用leave,它会崩溃。这里的问题是你调用某个组的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
}
And
和
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 **
}
}
}
This keeps the DispatchGroup
logic at one level of the app, keeping your classes less tightly coupled (e.g. the Geo coder doesn't need to know whether the view controller uses dispatch groups or not).
这将使DispatchGroup逻辑保持在应用程序的一个级别,减少类的紧密耦合(例如,Geo编码器不需要知道视图控制器是否使用分派组)。
Frankly, I'm not clear why you're using dispatch group at all if there's only one call. Usually you'd put whatever you call inside the completion handler, simplifying the code further. You generally only use groups if you're doing a whole series of calls. (Perhaps you've just simplified your code snippet whereas you're really doing multiple calls. In that case, a dispatch group might make sense. But then again, you shouldn't be doing concurrent geocode requests, suggesting a completely different pattern, altogether.
坦白地说,我不清楚如果只有一个调用,为什么还要使用dispatch group。通常,您将调用的任何内容放入完成处理程序中,从而进一步简化代码。通常只在执行一系列调用时才使用组。(也许您只是简化了代码片段,而实际上您正在执行多个调用。在这种情况下,分派组可能是有意义的。但话说回来,您不应该执行并发的地理代码请求,这意味着完全不同的模式。
#2
0
Passed dispatchGroup as parameter with function call and it worked.
通过函数调用将dispatchGroup作为参数传递,并正常工作。
Geo.reverseG(coordinates, dispatchGroup, setValues)