相同的代码,我假设设备实际上由于某种原因实际更新了位置两次,即使我只调用一次startUpdatingLocation()并在didUpdateLocations中运行一些stopUpdatingLocations()
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
let loc: CLLocation = locations[locations.count - 1]
let id = 0
let type = 0
let number = 0
createNewDataPoint(id, loc: loc, type: type, number: number)
}
在这种情况下,createNewDataPoint被调用两次,创建2个新数据点。它只在模拟器中发生一次,所以我假设它与实际设备和GPS有关,因为模拟器伪造了它的位置。
startUpdatingLocation()只在我的代码中一次,在一个按钮上。基本上,你单击按钮,去go manager.startUpdatingLocations(),didUpdateLocations在模拟器上点击一次,在设备上点击两次(相同的坐标),它会创建2个新的数据点。
提及任何相关内容的唯一其他代码是设置准确性,过滤器,授权请求以及前面提到的startUpdatingLocation()。有什么我可以做的,以确保我没有创建两倍于必要的数据点?
答案 0 :(得分:15)
可以在任何时候非常频繁地调用位置管理器委托方法。
但是,您可以应用以下算法来保护自己:
bool
说didFindLocation
。didFindLocation
时,将false
设为startUpdatingLocation
。didUpdateLocations:
,如果didFindLocation
为false
,请将didFindLocation
设置为true
,然后致电stopUpdatingLocation
。希望这有帮助。
答案 1 :(得分:8)
最好的方法如下:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
manager.delegate = nil
}
答案 2 :(得分:6)
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
[locationManager stopUpdatingLocation]; // stop location manager
locationManager.delegate = nil;
//Your logics...
//This will be called only one time now.
}
但不要忘记再次设置委托。
答案 3 :(得分:0)
你不会经常在模拟器上。当你移动很远的地方时,只有你得到didUpdateLocations
。只需移动到开放空间,GPS就可以识别您的设备位置,从而获得最佳准确度。
答案 4 :(得分:0)
不是开始/结束位置更新并将委托设置为nil,而是有一种名为requestLocation的方法,当您的应用程序需要快速修复用户的位置时,它是理想的:
来自文档:
override func viewDidLoad() {
// Create a location manager object
self.locationManager = CLLocationManager()
// Set the delegate
self.locationManager.delegate = self
}
func getQuickLocationUpdate() {
// Request location authorization
self.locationManager.requestWhenInUseAuthorization()
// Request a location update
self.locationManager.requestLocation()
// Note: requestLocation may timeout and produce an error if authorization has not yet been granted by the user
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Process the received location update
}
当您需要用户的当前位置但不需要保持位置服务运行时,请使用此方法。
答案 5 :(得分:0)
我尝试这样的代码:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[self.locationManager stopUpdatingLocation];
self.locationManager.delegate = nil;
self.locationManager = nil;
}
最后这个委托只被调用一次,我现在明白为什么会出现问题,只是因为经理调用stopUpdatingLocation
方法,但系统无法帮助我们使委托无效,所以我们可以收到回调每次由于desiredAccuracy
的{{1}}和distanceFilter
属性设置而导致位置更新,因此最终的解决方案就像@Zumry Mohamed所说的那样,我们可以手动将委托设置为nil我们CLLocationManager
。希望它能帮助你理解为什么这可以解决这个问题。
答案 6 :(得分:0)
获得所需的纬度和经度后,只需致电stopUpdatingLocation()
并将代表设为nil
。
在Swift 3中:
locationManager.stopUpdatingLocation()
locationManager.delegate = nil
在Objective-C中:
[locationManager stopUpdatingLocation]
locationManager.delegate = nil
此处locationManager
是CLLocationManager
的对象。
答案 7 :(得分:0)
locationManager.startUpdatingLocation()连续获取位置并且didUpdateLocations方法多次调用, 只需在调用locationManager.startUpdatingLocation()之前设置locationManager.distanceFilter值的值。
当我设置200米(你可以根据你的要求改变)工作正常
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 200
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
答案 8 :(得分:0)
另一种方法是设置时间间隔来打开和关闭委托,以及位置管理器。
var locationManagerUpdate:Bool = false //Global
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function "updateCounting" with the interval of 10 seconds
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.updateLocationManager), userInfo: nil, repeats: true)
}
@objc func updateLocationManager() {
if locationManagerUpdate == false {
locationManager.delegate = self
locationManagerUpdate = true
}
}
extension lm_gest: CLLocationManagerDelegate {
// Handle incoming location events.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locationManagerUpdate == true {
manager.stopUpdatingLocation()
manager.delegate = nil
}
//your code here...
}