2015-02-18 6 views
2

Следующий код не работает должным образом.Как я могу получить доступ к переменному внешнему блоку?

func convertToStreet(location:CLLocationCoordinate2D) -> CLPlacemark { 

    var tempLocation = CLLocation(latitude: location.latitude, longitude: location.longitude) 

    var temPlacemark:CLPlacemark? 

    CLGeocoder().reverseGeocodeLocation(tempLocation, completionHandler: {(placemarks, error) in 

     temPlacemark = (placemarks[0] as CLPlacemark) 
     println(temPlacemark!.thoroughfare) 

    }) 

    return temPlacemark! 
} 

Println внутри обработчика завершения работает правильно, но значение temPlacemark равна нулю в конце кода. Почему это происходит? Я очень благодарю вас за это.

+0

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

+0

Спасибо всем !!! – storybored

ответ

2

Это потому, что completionHandler называется асинхронно. Для этого вам нужно иметь блок обратного вызова в вашей пользовательской функции, чтобы вернуть значение, как только вы получите его от CLGeocoder.

Что-то вроде этого:

func convertToStreet(coordinate: CLLocationCoordinate2D, completionHandler: (placemark: CLPlacemark!, error: NSError!) -> Void) { 
    let tempLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) 

    CLGeocoder().reverseGeocodeLocation(tempLocation) { placemarks, error in 
     completionHandler(placemark: placemarks?.first as CLPlacemark?, error: error) 
    } 
} 

Вы бы тогда называть это так:

convertToStreet(location.coordinate) { placemark, error in 
    if placemark != nil { 
     // use `placemark` here 
     println(placemark.thoroughfare) 
    } else { 
     println(error) 
    } 
} 

// but don't use `placemark` here 
+0

Спасибо, @Rob! Я просто пытался дать общее представление о том, что я предлагаю в качестве решения. Но я определенно не должен был писать этот пример, поскольку язык, который я знаю, - Objective-C, а не Swift. – Gorka

+0

Не стесняйтесь делать это;) @Rob – Gorka

0

Проблема кода является то, что блок кода:

temPlacemark = (placemarks[0] as CLPlacemark) 
println(temPlacemark!.thoroughfare) 

будет выполняться позже.

Это означает, что текущая инструкция return всегда возвращает неинициализированное значение. Если вы хотите инициализировать этот var в своем блоке, вы должны сделать его property вашего объекта.

Смежные вопросы