我对iOS开发(我的第一个应用程序)很陌生,我遇到了这个问题。
我有一个iPhone应用程序,应该在用户按钮触摸时获得用户在多个ViewControllers中的当前位置。为了防止冗余代码(在不同的视图控制器中多次实现locationManager:didFailWithError
,locationManager:didUpdateToLocation:fromLocation
等),我决定创建一个名为LocationManager
的自定义类:
LocationManager.h
@interface LocationManager : NSObject <CLLocationManagerDelegate> {
@private
CLLocationManager *CLLocationManagerInstance;
id<LocationManagerAssigneeProtocol> assignee;
}
-(void) getUserLocationWithDelegate:(id) delegate;
LocationManager.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 的协议,我的ViewControllers实现了
@protocol LocationManagerAssigneeProtocol <NSObject>
@required
-(void) didUpdateToLocation:(CLLocation *) location;
@end
并在我的viewcontroller中需要
- (IBAction)getMyLocation:(id)sender {
[locationMgr getUserLocationWithDelegate:self];
}
这段代码完美无缺,然而,我感觉我在这里违反了一些设计模式,让LocationManager
能够调用自己发起对位置管理器调用的类的功能。另一方面,我不想为所有应该使用位置的视图控制器实现 CLLocationManagerDelegate 。
这个问题有更好的解决方案吗?
答案 0 :(得分:2)
我同意@CarlVeazey对此的看法。 Delegate非常适合任何时候存在的1对1关系,但在您的情况下,您可能需要多个viewControllers来响应任何给定时间的位置事件。因此,只需删除与您的委托及其相关协议相关的任何内容。
我可能会将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];
}
希望这有帮助并且有意义。