Как установить параметр Inout внутри замыкания

Итак, мой вопрос заключается в следующем: я пытаюсь реализовать расширение для CLGeoCoder, чтобы иметь возможность получить название города из CLLocation, но я сталкиваюсь с проблемой, когда пытаюсь установить строку с именем inout city внутри обработчика завершения в reverseGeocodeLocation

Вот мой код для моего расширения:

extension CLGeocoder {

  func findCityName(location:CLLocation, inout cityName:String) -> Void{
      self.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in

        // Place details
        var placeMark: CLPlacemark!
        placeMark = placemarks?[0]

        // Address dictionary
        print(placeMark.addressDictionary)



        // City
        if let city = placeMark.addressDictionary!["City"] as? String {
            cityName = city
        } 
      })
  } 
} 

Цель этого расширения - установить строку с названием города, передав ее по ссылке на эту функцию.

Примером может быть:

var cityName = ""
let location:CLLocation(latitude: 1, longitude: 1)
let geocoder: CLGeocoder()
geocoder.findCityName(location, &cityName)

///Later on in the process I would want to be able to use cityName for different purposes in my code 

Проблема, с которой я сталкиваюсь, заключается в том, что после задания ссылки на cityName в завершение Handler значение cityName остается пустым вне обработчика завершения.

Я новичок в swift, поэтому я, возможно, что-то упустил в указателях или в том, как их использовать, но у меня было понимание, что inout позволит изменить значение переменной внутри функции или обработчика закрытия / завершения.

Заранее благодарю за любую информацию, которую вы можете дать мне по этой проблеме, с которой я сталкиваюсь.

Мартин

1 ответ

В момент выхода из функции findCityName переменная cityName не изменялась. Обработчик завершения reverseGeocodeLocation в конечном итоге обновит переменную, которая является копией исходного cityName, а не той переменной, которую вы изначально передали в функцию. Обработчики завершения не выполняются сразу: они будут выполняться. Если бы они выполнялись сразу, функции могли бы просто возвращать свои результаты вместо использования обработчиков завершения, верно?

Теперь, я согласен с вами, это странно. Но странно не то, что Swift не обновляет переменную inout. Странно то, что Swift позволяет этой программе компилироваться. Потому что это не имеет смысла. Подписывайтесь на меня:

Представьте себе следующую функцию:

func f() {
    var cityName: String = ""
    findCityName(location, &cityName)
}

Когда вы вызываете его, переданная вами переменная cityName больше не существует, когда в конечном итоге выполняется обработчик завершения reverseGeocodeLocation. Функция f() давно вышла, а локальная переменная cityName исчезла из существования.

Понял? Бессмысленно даже надеяться, что переменная inout может быть обновлена.

Так. Теперь вы должны рефакторинг вашего кода. Может быть, использовать обработчик завершения.

Другие вопросы по тегам