为什么此代码每次更新位置两次?

时间:2014-11-22 15:43:57

标签: objective-c

这是代码,它一切正常,但每次我点击“获取我的位置”按钮它会更新位置两次,我找不到原因,任何想法?我从下面删除了很多代码,它仍然这样做,所以我知道它在这个部分的某个地方。感谢。

.h文件:

#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *LatitudeLabel;
@property (weak, nonatomic) IBOutlet UILabel *LongitudeLabel;
@property (weak, nonatomic) IBOutlet UILabel *GPSAccuracyLabel;
@property (weak, nonatomic) IBOutlet UILabel *AltitudeLabel;
@property (weak, nonatomic) IBOutlet UILabel *VerticalAccuracyLabel;

- (IBAction)getCurrentLocation:(id)sender;
@end

@interface MyLocationViewController : UIViewController <CLLocationManagerDelegate>
@end

.m文件:

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController {
CLLocationManager *locationManager;
}

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
locationManager = [[CLLocationManager alloc] init];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)getCurrentLocation:(id)sender {
locationManager.delegate = (id)self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error); UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [errorAlert show];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"Location updated: %@", newLocation);
CLLocation *currentLocation = newLocation;

if (currentLocation != nil) {
    _LatitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    _LongitudeLabel.text = [NSString stringWithFormat:@"%.6f", currentLocation.coordinate.longitude];
    _GPSAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.horizontalAccuracy];
    _AltitudeLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.altitude];
    _VerticalAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.verticalAccuracy];
}
每次按下按钮时

控制台输出:

2014-11-22 23:49:37.539 MyLocationDemo[914:60b] Location updated: <+10.16863927,+124.75859298> +/- 10.00m (speed 0.00 mps / course -1.00) @ 22/11/14 11:49:37 pm Philippine Standard Time

2014-11-22 23:49:37.545 MyLocationDemo[914:60b] Location updated: <+10.16863927,+124.75859298> +/- 10.00m (speed 0.00 mps / course -1.00) @ 22/11/14 11:49:37 pm Philippine Standard Time

2 个答案:

答案 0 :(得分:1)

在快速浏览Apple的文档后,我注意到您使用的委托方法- locationManager:didUpdateToLocation:fromLocation:自iOS 6以来已被弃用。
相反,您应该使用- locationManager:didUpdateLocations:

尝试使用下面的代码替换您的代码,看看它是否有任何区别:

编辑 - 我编辑了下面的代码来处理你得到的双重电话 从上面的帖子中我发现它们几乎是同时发生的,所以基本上我们会检查自上次通话以来是否至少已经过了1秒。
可能有更好的方法来做到这一点,但这只是我的头脑... ... Haven在Xcode中检查了它,但是,如果我还没有写错字或其他内容,它应该可以正常工作。

// ViewController.m  
@interface ViewController ()  
@property (nonatomic, strong) NSDate *lastUpdateTime;  // Create a property  
@end                                                   // to hold current time  

- (void)viewDidLoad {  
    [super viewDidLoad];  
    self.lastUpdateTime = [NSDate date];  // In viewDidLoad, 'initialize' it  
                                          // to get the current time  
}  

- (void)locationManager:(CLLocationManager *)manager
 didUpdateLocations:(NSArray *)locations  
{  
    NSTimeInterval passedTime = -[self.lastUpdateTime timeIntervalSinceNow];  
    // Here we are checking how much seconds have passed since our lastUpdateTime  
    // Since lastUpdateTime is in the past, the result will be negative, therefore  
    // the minus sign, so we'll get a positive number  

    if(passedTime < 1) {  
        return;  
    }  // Now we check if less than one second have passed. If so, the whole method  
       // will return. If not, it will just continue executing

    CLLocation *currentLocation = [locations lastObject];  
    self.lastUpdateTime = [NSDate date];  // Don't forget to update the lastUpdateTime  
                                          // To hold the new update time

    if (currentLocation != nil) {  
        NSLog(@"Location updated: %@", currentLocation);
        _LatitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];  
        _LongitudeLabel.text = [NSString stringWithFormat:@"%.6f", currentLocation.coordinate.longitude];  
        _GPSAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.horizontalAccuracy];  
        _AltitudeLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.altitude];  
        _VerticalAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.verticalAccuracy];  
    }  
}

答案 1 :(得分:0)

@ AMI289,你的想法奏效了,不再双重打电话了。

我在这里发布了最终代码以防其他人,我刚刚添加了locationManager = [[CLLocationManager alloc] init];

//  ViewController.m

#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSDate *lastUpdateTime; // create a property to hold current time.
@end

@implementation ViewController {
CLLocationManager *locationManager;
}

- (void)viewDidLoad {
[super viewDidLoad];
self.lastUpdateTime = [NSDate date];  // In viewDidLoad, 'initialize' it to get the current time
locationManager = [[CLLocationManager alloc] init];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)getCurrentLocation:(id)sender {
locationManager.delegate = (id)self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager
 didUpdateLocations:(NSArray *)locations
{
NSTimeInterval passedTime = -[self.lastUpdateTime timeIntervalSinceNow];
// Here we are checking how much seconds have passed since our lastUpdateTime
// Since lastUpdateTime is in the past, the result will be negative, therefore
// the minus sign, so we'll get a positive number

if(passedTime < 1) {
    return;
}  // Now we check if less than one second have passed. If so, the whole method
// will return. If not, it will just continue executing

CLLocation *currentLocation = [locations lastObject];
self.lastUpdateTime = [NSDate date];  // Don't forget to update the lastUpdateTime
// To hold the new update time

if (currentLocation != nil) {
    NSLog(@"Location updated: %@", currentLocation);
    _LatutideLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    _LongitudeLabel.text = [NSString stringWithFormat:@"%.6f", currentLocation.coordinate.longitude];
    _GPSAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.horizontalAccuracy];
    _AltitudeLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.altitude];
    _VerticalAccuracyLabel.text = [NSString stringWithFormat:@"%.2f", currentLocation.verticalAccuracy];
}
// Stop Location Manager
[locationManager stopUpdatingLocation];
}

@end