iPhone需要更新多个控制器中的位置

| 我试图在多个控制器上获取用户的当前位置,它们是导航控制器,tabbarcontroller,presentmodel控制器的一部分,因此基本上我真的不能做诸如self.navigationcontroller或self.tabBarController之类的事情。 我所做的是我创建了LocationHelper和LocationHelperDelegate
@protocol LocationHelperDelegate 
@required
- (void)locationUpdate:(CLLocation *)location; // Our location updates are sent here
- (void)locationError:(NSError *)error; // Any errors are sent here
@end

@interface LocationHelper : NSObject <CLLocationManagerDelegate>{
CLLocationManager *locationManager;
CLLocation *currentLocation;
id delegate;
}

@property (nonatomic, retain) CLLocation *currentLocation;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, assign) id delegate;
@end
然后在我的.m文件中执行以下操作
-(id) init {
    self = [super init];
    if(self != nil){
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
    }
    return self;
 }

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation    
   *)newLocation fromLocation:(CLLocation *)oldLocation {
    if([self.delegate conformsToProtocol:@protocol(LocationHelperDelegate)]) { 
        [self.delegate locationUpdate:newLocation];
    }
   }
现在这就是我在所有需要位置更新的控制器中正在做的事情。 在init方法中
    LocationHelper* locationHelper = [[LocationHelper alloc]init];
locationHelper.delegate = self;
[locationHelper.locationManager startUpdatingLocation];
然后我实现
 - (void)locationUpdate:(CLLocation *)location {
     latitude = location.coordinate.latitude;
     longitude = location.coordinate.longitude;
     [locationHelper.locationManager stopUpdatingLocation];
 }
我100%确信这样做不是正确的方法,但是我不知道应该如何做。基本上,我需要做的只是一次startUpdatingLocation,然后我的所有控制器都收到一个有关locationUpdate的通知,并且当每个人都收到了stopUpdatingLocation通知时。 我当时正在考虑让LocationHelper类具有单例,但是当所有控制器都获得它的实例时,他们可以将它们自身设置为委托,这似乎不正确,因为委托是LocationHelper中的实例变量之一,并且它只能容纳一个值。 如您所见,我很困惑,请帮助。     
已邀请:
我用来捕获来自多线程网络请求的响应的方法是使用NSNotificationCenter。它令人难以置信地易于实现,并且不需要您将变量保留在特定位置,例如AppDelegate。如果您以后决定重构代码,显然这会使事情变得更加灵活。 要发送通知,您可以使用如下代码。请注意,我们使用userInfo:paramater传递自定义数据。
[[NSNotificationCenter defaultCenter] postNotificationName:@\"requestFinished\"
                                                    object:self
                                                  userInfo:resultDictionary];
要订阅上述通知,请使用以下代码。不是该名称:与上面的postNotificationName:匹配。通过这种方式,您可以根据需要调度和订阅多个通知。
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(requestFinishedHandler:)
                                             name:@\"requestFinished\"
                                           object:nil];
这是如何访问传递到选择器的自定义用户数据的原型:如上定义。因为我可能想传递多个数据,所以我通过NSDictionary发送了数据。
- (void)requestFinishedHandler:(NSNotification *)notification
{
    resultDictionary = [notification userInfo];
}
    
一条只能代表一次的数据(例如“我的当前位置”,您只能有一个)应该位于只能存在一次的地方,例如单例。 您已经在使用一个非常好的单例。有一些人对此表示反对(上帝知道他们有充分的理由),但是对于此类数据,我没有将其全部保留在我的App Delegate中的第一个问题。 启动应用程序时,在应用程序委托中,我将使用应用程序委托本身作为位置管理器的委托来启动CLLocationManager。我将返回的CLLocation保留为委托的命名属性(例如\“ currentLocation \”),并在我从locationManager获取更新时将其覆盖。 然后在各种视图控制器中我可以说:
MyAppDelegate *del = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
CLLocation *current = del.currentLocation;
这样,您所有的位置获取/管理/存储位置都可以在一个位置上找到,您可以从应用程序中的任何位置访问该位置,并使所有内容保持整洁 编辑:在回答问题“按键值观察,您是指通知”时,答案是否定的。它们是完全不同的东西。 在任何视图控制器中-可能在viewDidLoad中-您可以说:
MyAppDelegate *del = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
[del addObserver:self forKeyPath:@\"currentLocation\" options:0 context:nil];
然后执行:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{
    MyAppDelegate *del = (MyAppDelegate *)object; 
    CLLocation *hereIAm = del.currentLocation;
    // and then do whatever with that
}
您在该方法的参数中对该键所做的更改有很多详细信息,但是可能更简单的方法是返回到委托并获取您要查找的值。 可能想在viewDidUnload中删除该观察者:
MyAppDelegate *del = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
[del removeObserver:self forKeyPath:@\"currentLocation\"];
    
您的位置助手应该是一个单例(这是一个很好的示例:http://www.galloway.me.uk/tutorials/singleton-classes/) 您应该使用通知而不是委托。位置帮助器单例应该在有新位置时发送通知,任何有兴趣的控制器都应订阅这些通知。     

要回复问题请先登录注册