ios 如何在ios中多次停止didUpdateLocations()的方法调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22292835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop multiple times method calling of didUpdateLocations() in ios
提问by Sujith Thankachan
This my code......
这是我的代码......
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(@"updated coordinate are %@",location_updated);
latitude1 = location_updated.coordinate.latitude;
longitude1 = location_updated.coordinate.longitude;
self.lblLat.text = [NSString stringWithFormat:@"%f",latitude1];
self.lblLon.text = [NSString stringWithFormat:@"%f",longitude1];
NSString *str = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",latitude1,longitude1];
url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection)
{
webData1 = [[NSMutableData alloc]init];
}
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(latitude1,longitude1);
marker.title = formattedAddress;
marker.icon = [UIImage imageNamed:@"m2.png"];
marker.map = mapView_;
marker.draggable = YES;
}
This method is call multiple times which i don't want.....
这个方法被多次调用,我不想要.....
采纳答案by nerowolfe
Add some restriction there. For timespan between locations and accuracy
在那里添加一些限制。位置和精度之间的时间跨度
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = locations.lastObject;
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
if (newLocation.horizontalAccuracy < 0) return;
// Needed to filter cached and too old locations
//NSLog(@"Location updated to = %@", newLocation);
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
double distance = [loc1 distanceFromLocation:loc2];
if(distance > 20)
{
_currentLocation = newLocation;
//significant location update
}
//location updated
}
回答by Sujith Thankachan
While allocating your LocationManager
object you can set the distanceFilter
property of the LocationManager
. Distance filter property is a CLLocationDistance
value which can be set to notify the location manager about the distance moved in meters. You can set the distance filter as follows:
虽然分配好自己的LocationManager
目标,你可以设置distanceFilter
的属性LocationManager
。距离过滤器属性是一个CLLocationDistance
值,可以设置它以通知位置管理器移动的距离(以米为单位)。您可以按如下方式设置距离过滤器:
LocationManager *locationManger = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = 100.0; // Will notify the LocationManager every 100 meters
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
回答by Raegtime
The easiest way:
最简单的方法:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
[manager stopUpdatingLocation];
manager.delegate = nil;
//...... do something
}
The manager can't find your didUpdateLocationsmethod without the delegatereference :-D
如果没有委托引用,经理将无法找到您的didUpdateLocations方法:-D
But don't forget to set it again before using startUpdatingLocation
但是不要忘记在使用startUpdatingLocation之前再次设置它
回答by Andrew Khapoknysh
I have similar situation. You can use dispatch_once:
我有类似的情况。您可以使用 dispatch_once:
static dispatch_once_t predicate;
- (void)update
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[_locationManager requestWhenInUseAuthorization];
}
_locationManager.delegate = self;
_locationManager.distanceFilter = kCLDistanceFilterNone;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
predicate = 0;
[_locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[manager stopUpdatingLocation];
manager = nil;
dispatch_once(&predicate, ^{
//your code here
});
}
回答by marcelosalloum
You can use a static variable to store the latest location timestamp and then compare it to the newest one, like this:
您可以使用静态变量来存储最新的位置时间戳,然后将其与最新的进行比较,如下所示:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[manager stopUpdatingLocation];
static NSDate *previousLocationTimestamp;
CLLocation *location = [locations lastObject];
if (previousLocationTimestamp && [location.timestamp timeIntervalSinceDate:previousLocationTimestamp] < 2.0) {
NSLog(@"didUpdateLocations GIVE UP");
return;
}
previousLocationTimestamp = location.timestamp;
NSLog(@"didUpdateLocations GOOD");
// Do your code here
}
回答by RyanTCB
You could set a flag (Bool). When you instantiate your locationsManager set flag = true then when locationManager:didUpdateLocations returns inside a code block that you want to run only once set flag = false. This way it will only be run the once.
你可以设置一个标志(布尔)。当你实例化你的locationsManager set flag = true 然后当locationManager:didUpdateLocations 在你只想运行一次的代码块中返回时设置flag = false。这样它只会运行一次。
if flag == true {
flag = false
...some code probably network call you only want to run the once
}
locations manager will be called multiple times but the code you want to execute only once, and I think that is what you are trying to achieve?
位置管理器将被多次调用,但您只想执行一次的代码,我认为这就是您想要实现的目标?
回答by Charan Giri
Write this method when ever you want to stop updating location manager
当您想停止更新位置管理器时编写此方法
[locationManager stopUpdatingLocation];
回答by tmr
for the time constraint, i did not understand code from accepted answer, posting a different approach. as Rob points out "When you first start location services, you may see it called multiple times". the code below acts on the first location, and ignores the updated locations for first 120 seconds. it is one way to address orginal question "How to stop multiple times method calling of didUpdateLocations".
由于时间限制,我不明白接受的答案中的代码,发布了不同的方法。正如 Rob 指出的“当您第一次启动定位服务时,您可能会看到它被多次调用”。下面的代码作用于第一个位置,并在前 120 秒内忽略更新的位置。这是解决原始问题“如何多次停止 didUpdateLocations 的方法调用”的一种方法。
in .h file:
在 .h 文件中:
@property(strong,nonatomic) CLLocation* firstLocation;
in .m file:
在 .m 文件中:
// is this the first location?
CLLocation* newLocation = locations.lastObject;
if (self.firstLocation) {
// app already has a location
NSTimeInterval locationAge = [newLocation.timestamp timeIntervalSinceDate:self.firstLocation.timestamp];
NSLog(@"locationAge: %f",locationAge);
if (locationAge < 120.0) { // 120 is in seconds or milliseconds?
return;
}
} else {
self.firstLocation = newLocation;
}
// do something with location
回答by Devendra Singh
locationManager.startUpdatingLocation() fetch location continuously and didUpdateLocations method calls several times, Just set the value for locationManager.distanceFilter value before calling locationManager.startUpdatingLocation().
locationManager.startUpdatingLocation() 连续获取位置并多次调用 didUpdateLocations 方法,只需在调用 locationManager.startUpdatingLocation() 之前设置 locationManager.distanceFilter 的值即可。
As I set 200 meters(you can change as your requirement) working fine
因为我设置了 200 米(你可以根据你的要求改变)工作正常
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 200
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
回答by Pramanshu
you can write : [manager stopUpdatingLocation]; manager = nil; in didupdatelocation delegate
你可以写: [manager stopUpdatingLocation]; 经理=零;在 didupdatelocation 委托中