1

我使用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

確實,已經做到了這一點,它的工作。謝謝 –

回答

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

0

傳遞dispatchGroup與函數調用參數和它的工作。

Geo.reverseG(coordinates, dispatchGroup, setValues)