Swift: 访问存储为变量的闭包参数
Swift: Accessing argument of closure stored as variable
我 运行 进入位置管理器的一些代码 class 并且我注意到有一个变量包含一个闭包。
var locationInfoCallBack: ((_ info: LocationInformation) -> ())!
我似乎无法访问变量的基础参数,这是首选。是否可以从上述变量中检索 LocationInformation
?
我的理解是,通过像这样传入 info 参数 self.locationInfoCallBack(info)
,'start' 函数将重新 运行:
根据我的经验,没有必要回忆 locationManager.requestAlwaysAuthorization()
或 locationManager.startUpdatingLocation()
代码如下:
class Location: NSObject, CLLocationManagerDelegate {
static let shared = Location()
let locationManager : CLLocationManager
var locationInfoCallBack: ((_ info: LocationInformation) -> ())!
override private init() {
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
super.init()
locationManager.delegate = self
}
func start(completion: @escaping(_ info: LocationInformation) -> Void) {
self.locationInfoCallBack = completion
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func stop() {
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else {
return
}
let info = LocationInformation()
info.latitude = mostRecentLocation.coordinate.latitude
info.longitude = mostRecentLocation.coordinate.longitude
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(mostRecentLocation) { (placemarks, error) in
guard let placemarks = placemarks, let placemark = placemarks.first else { return }
if let city = placemark.locality,
let state = placemark.administrativeArea,
let zip = placemark.postalCode,
let locationName = placemark.name,
let thoroughfare = placemark.thoroughfare,
let country = placemark.country {
info.city = city
info.state = state
info.zip = zip
info.address = locationName + ", " + (thoroughfare as String)
info.country = country
}
self.locationInfoCallBack(info)
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
}
}
class LocationInformation {
var city: String?
var address: String?
var latitude: CLLocationDegrees?
var longitude: CLLocationDegrees?
var zip: String?
var state: String?
var country: String?
init(city: String? = "", address: String? = "", latitude: CLLocationDegrees? = Double(0.0), longitude: CLLocationDegrees? = Double(0.0), zip: String? = "", state: String? = "", country: String? = "") {
self.city = city
self.address = address
self.latitude = latitude
self.longitude = longitude
self.zip = zip
self.state = state
self.country = country
}
}
如果底层参数不可访问,我当前的假设是变量 'locationInfoCallBack' 可用于检查 'start' 函数是否已完成。如果是这种情况,为什么不对相同的结果使用简单的布尔值呢?
当闭包为 运行 时,您可以从闭包代码访问参数,其值将是调用者传递的任何值。它与函数相同。除非函数(或闭包)是 运行,否则参数不存在。
I want it to be available app wide
那么,更合适的设计应该是不使用闭包。将闭包替换为:
var currentLocationInfo: LocationInformation?
可以删除 start
的参数:
func start() {
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
并且在 didUpdateLocation
中,将调用 self.locationInfoCallBack(info)
替换为对 currentLocationInfo
的简单赋值:
self.currentLocationInfo = info
现在您可以从任何地方访问:
Location.shared.currentLocationInfo
这会给你你得到的位置,最后一次 didUpdateLocation
被调用,你成功 reverse-geocoded 那。
请注意,这可能是 nil
,因为您可能在第一次成功之前访问它。 reverse-geocoded 一个位置。
我 运行 进入位置管理器的一些代码 class 并且我注意到有一个变量包含一个闭包。
var locationInfoCallBack: ((_ info: LocationInformation) -> ())!
我似乎无法访问变量的基础参数,这是首选。是否可以从上述变量中检索 LocationInformation
?
我的理解是,通过像这样传入 info 参数 self.locationInfoCallBack(info)
,'start' 函数将重新 运行:
根据我的经验,没有必要回忆 locationManager.requestAlwaysAuthorization()
或 locationManager.startUpdatingLocation()
代码如下:
class Location: NSObject, CLLocationManagerDelegate {
static let shared = Location()
let locationManager : CLLocationManager
var locationInfoCallBack: ((_ info: LocationInformation) -> ())!
override private init() {
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
super.init()
locationManager.delegate = self
}
func start(completion: @escaping(_ info: LocationInformation) -> Void) {
self.locationInfoCallBack = completion
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func stop() {
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let mostRecentLocation = locations.last else {
return
}
let info = LocationInformation()
info.latitude = mostRecentLocation.coordinate.latitude
info.longitude = mostRecentLocation.coordinate.longitude
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(mostRecentLocation) { (placemarks, error) in
guard let placemarks = placemarks, let placemark = placemarks.first else { return }
if let city = placemark.locality,
let state = placemark.administrativeArea,
let zip = placemark.postalCode,
let locationName = placemark.name,
let thoroughfare = placemark.thoroughfare,
let country = placemark.country {
info.city = city
info.state = state
info.zip = zip
info.address = locationName + ", " + (thoroughfare as String)
info.country = country
}
self.locationInfoCallBack(info)
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
locationManager.stopUpdatingLocation()
}
}
class LocationInformation {
var city: String?
var address: String?
var latitude: CLLocationDegrees?
var longitude: CLLocationDegrees?
var zip: String?
var state: String?
var country: String?
init(city: String? = "", address: String? = "", latitude: CLLocationDegrees? = Double(0.0), longitude: CLLocationDegrees? = Double(0.0), zip: String? = "", state: String? = "", country: String? = "") {
self.city = city
self.address = address
self.latitude = latitude
self.longitude = longitude
self.zip = zip
self.state = state
self.country = country
}
}
如果底层参数不可访问,我当前的假设是变量 'locationInfoCallBack' 可用于检查 'start' 函数是否已完成。如果是这种情况,为什么不对相同的结果使用简单的布尔值呢?
当闭包为 运行 时,您可以从闭包代码访问参数,其值将是调用者传递的任何值。它与函数相同。除非函数(或闭包)是 运行,否则参数不存在。
I want it to be available app wide
那么,更合适的设计应该是不使用闭包。将闭包替换为:
var currentLocationInfo: LocationInformation?
可以删除 start
的参数:
func start() {
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
并且在 didUpdateLocation
中,将调用 self.locationInfoCallBack(info)
替换为对 currentLocationInfo
的简单赋值:
self.currentLocationInfo = info
现在您可以从任何地方访问:
Location.shared.currentLocationInfo
这会给你你得到的位置,最后一次 didUpdateLocation
被调用,你成功 reverse-geocoded 那。
请注意,这可能是 nil
,因为您可能在第一次成功之前访问它。 reverse-geocoded 一个位置。