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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:40:33  来源:igfitidea点击:

How to stop multiple times method calling of didUpdateLocations() in ios

iosiphonecllocationmanagercllocation

提问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 LocationManagerobject you can set the distanceFilterproperty of the LocationManager. Distance filter property is a CLLocationDistancevalue 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 委托中