Почему я не могу использовать свойство `isCalculation`, чтобы дождаться завершения запроса на вычисление - PullRequest
0 голосов
/ 15 апреля 2019

Мне нужно вызвать метод calculate() класса MKDirections в цикле for, но я делаю слишком много запросов на допустимое расстояние, которое будет возвращено. Я попытался вставить цикл while, который продолжает цикл до тех пор, пока для свойства isCalculating не будет установлено значение false, но я все еще выполняю слишком много запросов, о чем свидетельствует сообщение error.debugDescription, которое выводится на печать. Как я могу дождаться окончания текущего запроса, прежде чем отправить другой?

Я пытался вставить цикл while, чтобы отложить отправку другого запроса методу calculate(), но код просто продолжает делать слишком много запросов, о чем свидетельствует error.debugDescription.

// Step through sites one by one
for siteIndex in 0..<countySites.count {
    var selectedSite = countySites[siteIndex]
    let destinationPlacemark = MKPlacemark(coordinate: selectedSite.locationCoordinate)

    request.destination = MKMapItem(placemark: destinationPlacemark)

    let distanceAndDirections = MKDirections(request: request)
    if currentCoordinate != nil {

        group.enter()
        busyCalculating = distanceAndDirections.isCalculating
        while busyCalculating == true {
            busyCalculating = distanceAndDirections.isCalculating
        }

        distanceAndDirections.calculate { (response, error) in

            if error == nil {

                let distanceInMetres = response?.routes.first?.distance
                let distanceInMiles = distanceInMetres! / 1610
                let roundedDistanceInMiles = Int(distanceInMiles.rounded())
                let distanceToSite = roundedDistanceInMiles

                selectedSite.distance = distanceToSite
                self.countySites[siteIndex] = selectedSite

            } else {
                print("error is not nil = \(error.debugDescription)")
            }

            group.leave()
        }

    }

}

1 Ответ

1 голос
/ 15 апреля 2019

Использование цикла while, который будет привязывать ЦП к 100% только для того, чтобы он мог проверить флаг, который в конечном итоге будет установлен в каком-то другом потоке, далек от идеального выбора.

Я предлагаю использовать group.wait. Вот примерная схема кода:

for siteIndex in 0..<countySites.count {
    let group = DispatchGroup()
    group.enter()
    distanceAndDirections.calculate { (response, error) in
        // stuff
        group.leave()
    })
    group.wait()
}

Обратите внимание на изменение, чтобы создать новую группу внутри цикла и исключить while занятый цикл.

Еще один вариант использования группы - использовать семафор.

Самая важная вещь здесь - убедиться, что ничего, что сделано внутри асинхронного блока, не приведет к любой попытке запустить код в той же очереди, что и основной цикл for.

И, конечно, вы должны убедиться, что этот основной цикл for не выполняется в главной очереди.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...