Функция не возвращает строку

Итак, я возвращаюсь к программированию и у меня возникла проблема. Моя функция не возвращает значение, когда я сохраняю значение в нем. Не могли бы вы, ребята, взглянуть и указать, почему это происходит?

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
    }
}
Другие вопросы по тегам