3

我对 iOS 开发(我的第一个应用程序)很陌生,我遇到了这个问题。

我有一个 iPhone 应用程序,它应该在用户按钮触摸时在多个 ViewControllers 中获取用户的当前位置。为了防止冗余代码(在不同的视图控制器中多次实现locationManager:didFailWithError,等),我决定创建一个名为的自定义类:locationManager:didUpdateToLocation:fromLocationLocationManager

位置管理器.h

@interface LocationManager : NSObject <CLLocationManagerDelegate> {
@private
    CLLocationManager *CLLocationManagerInstance;
    id<LocationManagerAssigneeProtocol> assignee;
}

-(void) getUserLocationWithDelegate:(id) delegate;

位置管理器.m

@implementation LocationManager

-(id)init {
    self = [super init];
    if(self) {
        CLLocationManagerInstance = [[CLLocationManager alloc] init];
        CLLocationManagerInstance.desiredAccuracy = kCLLocationAccuracyBest;
        CLLocationManagerInstance.delegate = self;
    }
    return self;
}

-(void) getUserLocationWithDelegate:(id) delegate {
    if([CLLocationManager locationServicesEnabled]) {
        assignee = delegate;
        [CLLocationManagerInstance startUpdatingLocation];
    }
}

#pragma CLLocationManagerDelegate

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

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    [CLLocationManagerInstance stopUpdatingLocation];
    [assignee didUpdateToLocation:newLocation];
}

我有一个名为LocationManagerAssigneeProtocol的协议,我的 ViewController 实现了该协议

@protocol LocationManagerAssigneeProtocol <NSObject>

@required
-(void) didUpdateToLocation:(CLLocation *) location;

@end

并在我需要的视图控制器中

- (IBAction)getMyLocation:(id)sender {

    [locationMgr getUserLocationWithDelegate:self];
}

这段代码运行良好,但是,我觉得我在这里违反了一些设计模式,因为我允许LocationManager调用本身发起对位置管理器的调用的类的函数。另一方面,我不想为所有应该使用位置的视图控制器实现CLLocationManagerDelegate 。

这个问题有更好的解决方案吗?

4

1 回答 1

2

我同意@CarlVeazey 的观点。委托非常适合在任何时候存在的一对一关系,但是在您的情况下,您似乎可能需要多个视图控制器来在任何给定时间响应位置事件。因此,只需删除与您的委托及其相关协议相关的任何内容。

我可能会将 LocationManager 类设为单例并修改更新方法:

+(LocationManager *)sharedInstance
{
    static LocationManager *_sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[self alloc] init];
    });

    return _sharedInstance;
}

-(void)getUserLocation
{
    if ([CLLocationManager locationServicesEnabled])
        [CLLocationManager startUpdatingLocation];
}

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{
    [CLLocationManagerInstance stopUpdatingLocation];
    [[NSNotificationCenter defaultCenter] postNotificationWithName:@"LocationManagerDidUpdateLocation" object:newLocation];
}

...然后任何需要使用此类的 viewController 都将具有以下内容:

-(void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserverForName:@"LocationManagerDidUpdateLocation" object:self queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        CLLocation *location = note.object;
        ...
    }];
}

-(IBAction)getMyLocation:(id)sender {
    [[LocationManager sharedInstance] getUserLocation];
}

希望这会有所帮助并且有意义。

于 2013-04-23T15:35:42.077 回答