2016-09-22 2 views
0

신속하게 다음을 수행하려고합니다. 배열의 주소 목록을 역방향으로 디코딩하고 위도/경도 좌표를 인쇄하려고합니다. 내가 가지고있는 코드는 다음과 같습니다.Swift : for 루프의 비동기 호출

let addressArray = ["Address 1", "Address 2"] 
    var coordinatesArray = [CLLocationCoordinate2D]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     createAddressList() 
     printAddressList() 
    } 

    func printAddressList() { 
     for i in 0 ..< addressArray.count { 
      print("Address = \(addressArray[i]) Coordinates = \(coordinatesArray[i].latitude),\(coordinatesArray[i].latitude)") 
    } 

    func createAddressList() { 
     for i in 0 ..< addressArray.count { 
      let address = addressArray[i] 
      geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in 
       print("Address = \(address)"); 
       if let placemark = placemarks?.first { 
        let coordinate = placemark.location?.coordinate 
        self.coordinatesArray.append(coordinate!) 
       } 
      }) 
     } 
    } 
} 

코드는 디코딩 된 첫 번째 주소 만 인쇄하고 아무 일도 일어나지 않습니다.

나는 것, 후자의 솔루션은 작동하더라도, 나는 그것이 깨끗하지의 볼이

func createAddressList() { 
    if count < self.addressArray.count { 
     let address = addressArray[count] 
     geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in 
      print("Address = \(address)"); 
      if let placemark = placemarks?.first { 
       let coordinate = placemark.location?.coordinate 
       self.coordinatesArray.append(coordinate!) 
      } 
      print("Count = \(self.count)") 
      self.count += 1 
      self.createAddressList() 
     }) 
    } else { 
     printAddressList() 
    } 
} 

처럼의 viewDidLoad 방법에서 printAddressList 호출을 이동하는 일, 다음 등이에 대한 수정을해야합니까 코드를 읽기 쉽고 깨끗하게 만드는 동시에 올바른 방법을 알고 싶습니다.

답변

3

이 구조를 사용하는 것은 어떻습니까?

let workGroup = dispatch_group_create() 

for i in 0..<addressArray.count { 

    dispatch_group_enter(workGroup) 

    performGeoCoding({ successCallback : 

      dispatch_group_leave(workGroup) 

    }) 
} 

dispatch_group_notify(workGroup, dispatch_get_main_queue()){ 
    successCallback() 
    printAddressList()      
} 

는 dispatch_group here에 대한 아주 좋은 튜토리얼있다.

+0

먼저 제안에 감사드립니다. 나는 당신이 준 링크로부터 파견단에 대해 더 많이 이해했다. 하지만 당신이 준 해결책을 이해할 수 없었습니다. 내 문제는 for 루프 내부에 지오 코딩 메서드가 있다는 것입니다. 첫 번째 주소가 디코딩 될 때까지 for 루프는 두 번째 반복을 완료했습니다. 질문은 왜 내가 디코딩 된 두 번째 주소 (내 경우에는 지오 코드 내부의 print 문)를 보지 못하는지입니다. while 루프 대신 for 루프를 사용해야합니까? – sysuser

+0

for 루프를 사용하든 while 루프를 사용하든 관계없이 중요하다고 생각합니다. 제목에서 언급했듯이 printAddressList()가 호출되기 전에 완성 처리기의 결과가 반환되는 것을 보장하지 않는 비동기 호출입니다. 예를 들어 첫 번째 지오 코드 요청이 반환 될 때까지 프로그램은 이미 주소 배열을 통해 반복 한 다음 올바른 값을 인쇄하지 않는 printAddressList 함수를 실행할 수 있습니다. 그래서 완성 처리기에서 원하는 결과를 모두 수집 할 때까지 기다릴 수 있도록 dispatch_group을 사용해야한다고 생각하는 이유입니다. – woogii

+0

사실, 알림이있는 발송 처리기가 작동합니다. – sysuser