ios – SWIFT – LocationManager循环多次?

我有一个locationManager函数获取用户当前位置并发布城市和州的名称.我有一个打印声明,所以我可以在我的控制台检查一切是否正常工作……事实确实如此.但是,它打印城市位置3次.这实际上在我的实际应用程序中引起了一个问题,但这超出了这个问题的范围.

我的功能如下:

var usersLocation: String!

var locationManager: CLLocationManager!

func locationManager(manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) {

    let userLocation: CLLocation = locations[0]


    CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks,error) -> Void in

        if error != nil {

            print(error)

        } else {

            let p = placemarks?.first // ".first" returns the first element in the collection,or nil if its empty
            // this code above will equal the first element in the placemarks array

            let city = p?.locality != nil ? p?.locality : ""
            let state = p?.administrativeArea != nil ? p?.administrativeArea : ""

            self.navigationBar.title = ("\(city!),\(state!)")
            self.usersLocation = ("\(city!),\(state!)")
            self.locationManager.stopUpdatingLocation()
            print(self.usersLocation)
            self.refreshPosts()
        }
    }
}

所以在我的print(self.usersLocation)中,它将在我的控制台中打印三次.这是正常的吗?

更新显示视图

override func viewDidLoad() {
    super.viewDidLoad()

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 250.0
}

解决方法

我首先建议一些事情:

>在执行reverseGeocodeLocation之前调用stopUpdatingLocation.

您在reverseGeocodeLocation完成处理程序闭包内调用stopUpdatingLocation.问题是这是异步运行的,因此在更新期间,didUpdateLocations可能会收到额外的位置更新.通常,当您第一次启动位置服务时,您将获得许多更新,通常会提高准确性(例如,水平精度值越来越小).如果在启动异步地理编码请求之前关闭位置服务,则可以最大限度地减少此问题.
>您还可以在viewDidLoad中添加distanceFilter,这将最大程度地减少对委托方法的冗余调用

locationManager.distanceFilter = 1000

>您可以使用自己的状态变量来检查反向地理编码过程是否已启动.例如:

private var didPerformGeocode = false

func locationManager(manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) {
    // if we don't have a valid location,exit

    guard let location = locations.first where location.horizontalAccuracy >= 0 else { return }

    // or if we have already searched,return

    guard !didPerformGeocode else { return }

    // otherwise,update state variable,stop location services and start geocode

    didPerformGeocode = true
    locationManager.stopUpdatingLocation()

    CLGeocoder().reverseGeocodeLocation(location) { placemarks,error in
        let placemark = placemarks?.first

        // if there's an error or no placemark,then exit

        guard error == nil && placemark != nil else {
            print(error)
            return
        }

        let city = placemark?.locality ?? ""
        let state = placemark?.administrativeArea ?? ""

        self.navigationBar.title = ("\(city),\(state)")
        self.usersLocation = ("\(city),\(state)")
        print(self.usersLocation)
        self.refreshPosts()
    }
}

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...