Как заблокировать что-либо, пока функция не будет завершена? - PullRequest
0 голосов
/ 01 июня 2018

Я осматривался и не нашел способа предотвратить что-либо, пока функция не будет завершена.По сути, события, которые находятся ниже функции, происходят до того, как функция будет.Позвольте мне показать вам код и вывод консоли.

Код:

if locationSwitch.isOn == true {
            let url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(location.latitude),\(location.longitude)&result_type=locality&key=AIzaSyDI-ZacHyPbLchRhkoaUTDokwj--z_a_jk"
            loadUrl(url: url) { optionalLocation in
                guard let nonOptionalLocation = optionalLocation else {
                    // Location was nil; Handle error case here
                    return
                }
                // Do something with your location here, like setting UI or something
                print("Optional Location: \(optionalLocation)")
                print("nonOptional Location: \(nonOptionalLocation)")
                cityState = nonOptionalLocation
                print("cityState: \(cityState)")
                print("Within Func")
            }
            print("Within If")
        } else {
            lat = 0.0
            lng = 0.0
            cityState = ""
        }
        print("After If")
        print("cityState Outside If Statement: \(cityState)")
        CoreDataHandler.savePhotoObject(locationCoordinateLatitude: lat, locationCoordinateLongitude: lng, locationLocality: cityState, dateCreated: date, discription: discriptionBox.text!, photo: selectedImageData!)
    }

Выход на консоль:

Before If
Within If
After If
cityState Outside If Statement:
Optional Location: Optional("San Francisco, CA, USA")
nonOptional Location: San Francisco, CA, USA
cityState: San Francisco, CA, USA
Within Func

Как видите,

Optional Location: Optional("San Francisco, CA, USA")
nonOptional Location: San Francisco, CA, USA
cityState: San Francisco, CA, USA
Within Func

должно предшествовать

Within If

Я полагаю, что это происходит потому, что для завершения функции loadUrl требуется столько времени, что код проходит через нее и завершает код, затем loadUrl завершается, а затем печатается после всего остального.Это не было бы проблемой, за исключением того, что переменная, установленная равной nonOptionalLocation, вызывается после завершения функции loadUrl, а поскольку loadUrl завершает работу после завершения кода, переменная, которая должна быть равнаnonOptionalLocation на самом деле равно "".

Кто-нибудь знает, как это можно сделать прямо сейчас, я думаю, что мне нужно что-то блокировать до тех пор, пока loadUrl не будет завершено, но если вы знаете оЕще один способ сделать это, пожалуйста, поделитесь.Благодарю вас.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Использовали ли вы DispatchQueue.main.sync {}, возможно, он на некоторое время застрял в вашем пользовательском интерфейсе, что не очень хорошо, но если у вас нет проблем с этим, вы можете попробовать это.

if locationSwitch.isOn{

        DispatchQueue.main.sync {

            let url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=\(location.latitude),(location.longitude)&result_type=locality&key=AIzaSyDI-ZacHyPbLchRhkoaUTDokwj--z_a_jk"

            loadUrl(url: url) { optionalLocation in
                guard let nonOptionalLocation = optionalLocation else {
                    return
                }

                print("Optional Location: \(optionalLocation)")
                print("nonOptional Location: \(nonOptionalLocation)")
                cityState = nonOptionalLocation
                print("cityState: \(cityState)")
                print("Within Func")
            }
        }
        print("Within If")
    } else {
        lat = 0.0
        lng = 0.0
        cityState = ""
    }
    print("After If")
    print("cityState Outside If Statement: \(cityState)")
    CoreDataHandler.savePhotoObject(locationCoordinateLatitude: lat, locationCoordinateLongitude: lng, locationLocality: cityState, dateCreated: date, discription: discriptionBox.text!, photo: selectedImageData!)
0 голосов
/ 01 июня 2018

loadUrl работает асинхронно, просто поместите код для выполнения после возврата данных в блок завершения

if locationSwitch.isOn == true {
    loadUrl(url: url) { optionalLocation in
        guard let nonOptionalLocation = optionalLocation else {
            // Location was nil; Handle error case here
            return
        }
        // Do something with your location here, like setting UI or something
        print("Optional Location: \(optionalLocation)")
        print("nonOptional Location: \(nonOptionalLocation)")
        cityState = nonOptionalLocation
        print("cityState: \(cityState)")
        print("Within Func")
        DispatchQueue.main.async {
            CoreDataHandler.savePhotoObject(locationCoordinateLatitude: lat, locationCoordinateLongitude: lng, locationLocality: cityState, dateCreated: date, discription: discriptionBox.text!, photo: selectedImageData!)
        }
    }
} else {
    CoreDataHandler.savePhotoObject(locationCoordinateLatitude: 0.0, locationCoordinateLongitude: 0.0, locationLocality: "", dateCreated: date, discription: discriptionBox.text!, photo: selectedImageData!)
}
...