Ios CoreLocations ReverseGeoLocation使其每分钟仅运行/循环一次

Ios CoreLocations ReverseGeoLocation使其每分钟仅运行/循环一次,ios,objective-c,loops,core-location,Ios,Objective C,Loops,Core Location,HiallI正在使用Corelocation并将基本long、lat等更新为每秒尽可能多的时间,这是我想要的,但我现在引入了ReverseGeoLocation,我只希望它每分钟运行/地理编码一次位置。目前它也在尽可能多地更新,苹果说这是不好的,只希望它每分钟更新一次 有人能告诉我怎么做吗?(尽可能多地保存我的主corelocation更新,但让我的ReverseGeoLocation每分钟运行一次。) 我已经尝试了多种不同的方法来限制使用计时器运行的reverseGeocodeLocation

HiallI正在使用Corelocation并将基本long、lat等更新为每秒尽可能多的时间,这是我想要的,但我现在引入了ReverseGeoLocation,我只希望它每分钟运行/地理编码一次位置。目前它也在尽可能多地更新,苹果说这是不好的,只希望它每分钟更新一次

有人能告诉我怎么做吗?(尽可能多地保存我的主corelocation更新,但让我的ReverseGeoLocation每分钟运行一次。)

我已经尝试了多种不同的方法来限制使用计时器运行的reverseGeocodeLocation的数量,如果语句和分派没有成功,我尝试的其他方法如下,我不确定我是否需要在执行地理代码时暂停代码,或者???我的corelocation代码是相当标准的苹果示例代码。 任何帮助都会很好

//下面的代码不显示所有代码,但显示相关部分等

.h
@interface ViewController : UIViewController <CLLocationManagerDelegate>
//I set other standard property outlets for location, locationManager, labels etc
@property (nonatomic, strong) NSDate *reverseGeoLastUpdate; //my 60second reversegeoupdates

.m
@implementation ViewController {
NSTimer *timer;
}

- (void)viewDidLoad {
[super viewDidLoad];
[self startStandardUpdates];
}

- (void)startStandardUpdates {
if (nil == _locationManager)
_locationManager = [[CLLocationManager alloc] init];
geocoder = [[CLGeocoder alloc] init];
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[_locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
CLLocation* location = [locations lastObject];

NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
NSLog(@"eventDate timeIntervalSinceNow = %f", [eventDate timeIntervalSinceNow]);
if (abs(howRecent) < 15.0) {
self.coordinateLat.text = [NSString stringWithFormat:@"%f", location.coordinate.latitude]; 
当我尝试使用NSTimer来代替上面方法中的“//my timer”代码时,但是

“错误域=kCLErrorDomain代码=8”“操作无法完成”

当我试着 在触发方式和标签更新后发送,但一旦触发,它会连续触发每帧,并且无法确定如何使其每60秒运行一次

double delayInSeconds = 60.0;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
           ^(void){

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
    placemark = [placemarks lastObject];
    _address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                        placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 placemarks
                        ];
} else {
    NSLog(@"%@", error.debugDescription);
}
}];

});

任何关于如何正确执行此操作的帮助都是非常好的

您的第一个代码几乎是正确的,但是您需要考虑这样一个事实:反向地理代码将在后台线程上完成,并且您应该只更新主队列上的UI

if(self.reverseGeoLastUpdate == nil || [self.reverseGeoLastUpdate timeIntervalSinceNow] > 59 ) {
    self.reverseGeoLastUpdate = [NSDate date];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                          placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 place marker calls here
                          ];
               });
        } else {
            NSLog(@"%@", error.debugDescription);
        }

    }];
    }
}

另外,尝试改用u而不是
self
来访问属性,除非你故意想绕过setter/getter

Hi Paulw11谢谢你的回答是的,我还没有深入研究在不同线程上运行东西。当我执行你的代码时(我添加了debug 4 timeInterval)我现在得到了2014-12-18 12:28:16.028 myapp[16858:10068748]self.ReverseGeolasUpdate时间间隔现在0.000000 2014-12-18 12:28:16.207 myapp[16858:10068748]找到了placemarks:(null),错误:error Domain=kCLErrorDomain Code=8“操作无法完成。(kCLErrorDomain错误8。)“2014-12-18 12:28:16.207 myapp[16858:10068748]错误域=kCLErrorDomain代码=8”操作无法完成。(kCLErrorDomain错误8。)“?您也可以告诉我[16858:10068748]的作用是什么在我的调试控制台输出中是什么意思?我不知道这些数字是什么意思。我认为这与进程id和日期/时间有关。错误8的原因是因为您尝试反转地理代码的位置为零。在原始代码中,您使用的是
\u location
,我将其更改为
self.location
,但您的代码高于t不设置
self.location
/
\u location
它设置局部变量
location
。我已更新答案以删除
self。
double delayInSeconds = 60.0;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),
           ^(void){

[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
if (error == nil && [placemarks count] > 0) {
    placemark = [placemarks lastObject];
    _address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                        placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 placemarks
                        ];
} else {
    NSLog(@"%@", error.debugDescription);
}
}];

});
if(self.reverseGeoLastUpdate == nil || [self.reverseGeoLastUpdate timeIntervalSinceNow] > 59 ) {
    self.reverseGeoLastUpdate = [NSDate date];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.address1.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@\n",
                          placemark.subThoroughfare, placemark.thoroughfare,
                        //other 4 place marker calls here
                          ];
               });
        } else {
            NSLog(@"%@", error.debugDescription);
        }

    }];
    }
}