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
邏輯在應用程序中的一個級別,使您的班少緊密耦合(如地理編碼器並不需要知道視圖控制器是否使用派遣或不)。
坦率地說,我不清楚爲什麼你只使用一個調用來使用調度組。通常你會把任何你在完成處理程序中調用的內容,進一步簡化代碼。如果您正在進行一系列的通話,您通常只會使用羣組。 (也許你只是簡化了你的代碼片段,而你真的在做多次調用,那麼派遣組可能是有意義的,但是再一次,你不應該做併發地理代碼請求,這意味着完全不同的模式,乾脆。
來源
2017-08-06 17:52:57
Rob
每'leave'看漲期權必須有一個相關的'enter'電話。如果你打電話'leave',而不必首先調用'enter' ,它會崩潰,這裏的問題是你在某個組中調用了'enter',但'reverseG'在'ViewController'的其他實例上調用'leave',我建議傳遞'DispatchGroup'作爲參數指向'reverseG'方法,或者更好的是'reverseG'不應該離開組,而是將'leave'調用放入'reserveG'調用的完成處理程序中。 – Rob
確實,已經做到了這一點,它的工作。謝謝 –