Corelocation延迟

时间:2015-06-22 20:42:07

标签: ios objective-c location cllocationmanager

我为我的位置需求创建了一个帮助程序类,所以我没有违反DRY原则。这个类看起来像这样:
Location.h

@interface Location : NSObject <CLLocationManagerDelegate>{
CLLocationManager *manager;
CLGeocoder *geocoder;
CLPlacemark *placemark;
}

-(float)latitude;
-(float)longitude;
-(NSString *)postalcode;

Location.m

@implementation Location{
    float latitude;
    float longitude;
    NSString *postalcode;
}
-(id)init{
    NSLog(@"Hallo");
    [self setupLocationManager];
    return self;
}

-(float)latitude{

    return latitude;
}

-(float)longitude{

    return longitude;
}

-(NSString *)postalcode{

    return postalcode;
}

-(void)setupLocationManager{
    manager = [[CLLocationManager alloc] init];
    [manager requestWhenInUseAuthorization];
    manager.delegate = self;
    manager.desiredAccuracy = kCLLocationAccuracyBest;
    manager.distanceFilter = 100;
    [manager startUpdatingLocation];
    geocoder = [[CLGeocoder alloc] init];
 }

 #pragma mark - CLLocationManagerDelegate Methods

 - (void)locationManager:(CLLocationManager *)manager didFailWithError:          (NSError *)error
{

     NSLog(@"Error: %@", error);
     NSLog(@"Failed to get location! :(");

}

 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{

NSLog(@"Location: %@", newLocation);
CLLocation *currentLocation = newLocation;

if (currentLocation != nil) {

    latitude = currentLocation.coordinate.latitude;
    longitude = currentLocation.coordinate.longitude;


}

[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {

    if (error == nil && [placemarks count] > 0) {

        placemark = [placemarks lastObject];
        postalcode = [NSString stringWithFormat:@"%@",placemark.postalCode];
        /*
         self.address.text = [NSString stringWithFormat:@"%@ %@\n%@ %@\n%@\n%@",
         placemark.subThoroughfare, placemark.thoroughfare,
         placemark.postalCode, placemark.locality,
         placemark.administrativeArea,
         placemark.country];
         */
    } else {

        NSLog(@"%@", error.debugDescription);

    }

} ];

}


 @end

当我在ViewController中尝试创建Location实例并设置纬度和经度标签时,在viewDidLoad方法中,标签的值为0.00000。 显然,获取坐标需要大约半秒钟的位置。 我尝试过使用

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self setCoordinateLabels];
    });

但是,这看起来非常h​​acky并且可能不是最好的做法?那么有什么方法可以做到这一点更好吗?

1 个答案:

答案 0 :(得分:1)

嗯 - 这非常hacky。你为什么不转发你的委托方法电话?

locationManager:didUpdateToLocation:

(顺便说一下,这是遗留功能)

告诉您何时设置了第一个位置。您可以在Location课程中拥有一系列代表,并在适当的时候致电每位代表。

以下是块的示例:

static NSMapTable *listenerBlocks;

+ (void)addListener:(NSObject *)listener listenerBlock:(void (^)())listenerBlock
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        listenerBlocks =
        [NSMapTable mapTableWithKeyOptions:NSMapTableWeakMemory
                              valueOptions:NSMapTableStrongMemory];
    });
    if (listenerBlock && listener) {
        [listenerBlocks setObject:listenerBlock forKey:listener];
    }
}

+ (void)removeListener:(NSObject *)listener
{
    if (listener) {
        [listenerBlocks removeObjectForKey:listener];
    }
}

locationManager:didUpdateToLocation:中,您只需致电

NSArray *allBlocks = [[listenerBlocks objectEnumerator] allObjects];
for(void (^listenerBlock)(NSString *) in allBlocks)
{
    listenerBlock();
}

最后

在需要更新标签的类中(例如myLabel):

[Location addListener:self listenerBlock:^{
   dispatch_async(dispatch_get_main_queue(),^{
      //myLabel.text = //... update your label here
      [self setCoordinateLabels]; // as from your code above..
   });
}];