Функция не возвращает строку
Итак, я возвращаюсь к программированию и у меня возникла проблема. Моя функция не возвращает значение, когда я сохраняю значение в нем. Не могли бы вы, ребята, взглянуть и указать, почему это происходит?
func getLocation() -> NSString {
manager = OneShotLocationManager()
var tempLocation: NSString = "" // created an empty string for the var
manager!.fetchWithCompletion {location, error in
if let locatie = location {
tempLocation = String(locatie.coordinate.latitude) + "," + String(locatie.coordinate.longitude)
print(tempLocation) // It stores a value here but will not show it on the return
} else if let err = error {
tempLocation = err.localizedDescription
}
self.manager = nil
}
return tempLocation // It's not returning anything here..
}
4 ответа
Завершение начинается после выхода из функции, так что это проблема, я думаю. Вы возвращаете "", а затем делаете вещи внутри кода завершения
Ваша функция не возвращает значение, потому что fetchWithCompletion
выполняется после оператора return, поскольку он асинхронный. Вы можете изменить свою функцию, используя обработчик завершения, чтобы получить доступ к tempLocation
как только это будет установлено:
func getLocation(completion: (location: String) -> ()) {
manager = OneShotLocationManager()
var tempLocation: NSString = "" // created an empty string for the var
manager!.fetchWithCompletion {location, error in
if let locatie = location {
tempLocation = String(locatie.coordinate.latitude) + "," + String(locatie.coordinate.longitude)
print(tempLocation) // It stores a value here but will not show it on the return
} else if let err = error {
tempLocation = err.localizedDescription
}
self.manager = nil
completion(location: tempLocation)
}
}
Вы можете реализовать эту функцию следующим образом:
getLocation { (location) -> () in
print(location)
}
Закрытие предоставлено fetchWithCompletion()
вызывается асинхронно - после завершения выборки местоположения менеджера. Ваша функция начинает выборку менеджера, а затем возвращается до завершения выборки менеджера; Таким образом, первоначальное назначение tempLocation
это возвращение как ""
,
Поскольку выборка асинхронна, возможно, ваш getLocation()
также должен быть асинхронным?
func getLocationAsynch (handler: (String) -> Void) {
OneShotLocationManager()!.fetchWithCompletion { location, error in
if let locatie = location {
handler (String(locatie.coordinate.latitude) + "," + String(locatie.coordinate.longitude))
} else if let err = error {
handler (err.localizedDescription)
} else {
handler ("")
}
}
}
Вышеуказанное предотвращает блокировку вашего кода; возможно, когда местоположение станет доступным, вы просто отобразите его для пользователя?
Если, однако, вы хотите заблокировать. Использовать dispatch_semaphore
как:
// assuming dispatch_semaphore works in Swift
func getLocation () -> String {
let sem = dispatch_semaphore_create (0);
var result = ""
OneShotLocationManager()!.fetchWithCompletion { location, error in
if let locatie = location {
result = String(locatie.coordinate.latitude) + "," + String(locatie.coordinate.longitude)
} else if let err = error {
result = err.localizedDescription
}
dispatch_semaphore_signal(sem)
}
dispatch_semaphore_wait(sem)
return result
}
Вам нужно вызвать getLocation и делать свои вещи внутри замыкания fetchWithCompletion
func getLocation() {
manager = OneShotLocationManager()
manager!.fetchWithCompletion {location, error in
if let locatie = location {
tempLocation = String(locatie.coordinate.latitude) + "," + String(locatie.coordinate.longitude)
//DO THE THINGS YOU NEED TO DO WITH THE LOCATION HERE
} else if let err = error {
tempLocation = err.localizedDescription
}
self.manager = nil
}
}