2017-03-31 2 views
0

어떻게 클로저를 동기화 할 수 있습니까? ?어떻게 클로저를 동기화 할 수 있습니까?

나는이 코드를 가지고 : 내 코드에서

private func getWeather(parameters: [String : Any], failure: ((String) -> Void)? = nil ,completion: (() -> Void)? = nil) { 

     for _ in 0...10 { 

      RequestManager.sharedInstance.request(url: baseURL, parameters: parameters, completion: { (result) in 
       if JSON.parse(result)["name"].string == nil { 
        failure?("Something went wrong. Please, try again later") 
       } else { 
        let weatherModel: WeatherModel = WeatherModel(json: JSON.parse(result)) 
       } 
      }) 
     } 
     completion?() 

    } 

, 완료() 모든 요청 종료됩니다하지 않을 경우, 호출을 내가 완료 전화를 필요로하는 모든 요청()을 종료 할 때. 내가 할 수 있니?

+2

연구 'DispatchGroup'. – rmaddy

+0

[다음은 훌륭한 튜토리얼입니다.] (https://dispatchswift.com/introduction-to-dispatch-group-a5cf9d61ff4f) –

+0

또는 nsoperation (대기열) 및 설정 종속성에 대해 살펴보십시오 – vikingosegundo

답변

5

현재 허용되는 답변이 올바르지 않으므로 여기에 DispatchGroup을 올바르게 사용하는 버전이 있습니다.

private func getWeather(parameters: [String : Any], failure: ((String) -> Void)? = nil ,completion: (() -> Void)? = nil) { 
    let dispatchGroup = DispatchGroup() 
    for _ in 0...10 { 
     dispatchGroup.enter() 
     RequestManager.sharedInstance.request(url: baseURL, parameters: parameters) { result in 
      if JSON.parse(result)["name"].string == nil { 
       failure?("Something went wrong. Please, try again later") 
      } else { 
       let weatherModel: WeatherModel = WeatherModel(json: JSON.parse(result)) 
      } 
      dispatchGroup.leave() 
     } 
    } 

    dispatchGroup.notify(queue: DispatchQueue.main) { 
     completion?() 
    } 
} 
+0

고맙습니다. 나는 이것을 사용하기 시작할 것이고, 나의 받아 들인 대답을 삭제할 것이다 ... 또는 나는 받아 들인 대답을 삭제할 수 없다. ... – Sethmr

+0

오, @rmaddy, 너의 도움에 너무 고마워! – Banck

+0

@rmaddy 기여하고 싶다면 시나리오에 대한 메타 포스트를 만들었습니다. https://meta.stackoverflow.com/questions/346284/why-cant-i-delete-an-accepted-answer-posted-by-myself – Sethmr

0

쉬운 방법은 완료된 통화를 계산하는 것입니다.

private func getWeather(parameters: [String : Any], failure: ((String) -> Void)? = nil ,completion: (() -> Void)? = nil) { 
    let numCalls = 11; 
    var completedCalls = 0; 

    for _ in 0..<numCalls { 

     RequestManager.sharedInstance.request(url: baseURL, parameters: parameters, completion: { (result) in 
      if JSON.parse(result)["name"].string == nil { 
       failure?("Something went wrong. Please, try again later") 
      } else { 
       let weatherModel: WeatherModel = WeatherModel(json: JSON.parse(result)) 
      } 
      completedCalls += 1 
      if completedCalls == numCalls { 
       completion?() 
      } 
     }) 
    } 
} 

각 요청이 끝날 때 완료 콜백이 실행됩니다. 완료 콜백 각각을 둘러싸는 스코프 내의 값을 갱신하는 것은 끝난 요청의 수를 추적 할 수있게 해줍니다. 예상 한 모든 요청이 끝나면 completion?()으로 전화하십시오.

+0

예, 분명합니다.)) 그러나 우아한 해결책이 있다고 생각합니다. – Banck

+0

이 호출 계산 패턴을 추상화하는 함수를 만들 수 있습니다. 그것은 어떤 요청을하고 어떤 횟수로 만들 것인지, 또는 요청 목록을 취할 것입니다. –

+0

나는 이것을 통해 DispatchGroup을 사용하는 것이 좋습니다. – Sethmr

관련 문제