方法不从应用程序委托在iOS调用
我想从应用程序的其他地方调用一个方法来获取用户在应用程序委托中获得的位置。 当调用CLLocation *getCurLoc = [AppDelegate getCurrentLocation];
从另一个视图控制器,没有返回。
应用程序代表是,
@synthesize locationManager; CLLocation *location; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ locationManager = [[CLLocationManager alloc]init]; locationManager.delegate = self; locationManager.desiredAccuracy=kCLLocationAccuracyKilometer; [locationManager startUpdatingLocation]; return YES; } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ [locations lastObject]; [manager stopUpdatingLocation]; CLLocation *location = [locations lastObject]; } +(CLLocation *)getCurrentLocation{ return location; }
将其更改为带有“ – ”的实例方法不起作用。 应该把“位置”做成一个实例吗? 代表是否应该成为一个实例,还是有更好的方法从其他地方访问?
马丁的答案是一个有效的快速和肮脏的方式来解决这个问题的方式是符合你的方法 – 存储位置在appDelegate
。
如果你想更进一步,你可能会考虑实现一个特殊的对象来保存数据 – 数据模型。 将数据存储在应用程序委托中被认为是一种不好的做法 – 这不是它存在的地方(尽pipe它在样本或小应用程序中工作得很好)。
你可以做这样的事情:
DataModel.h
#import <Foundation/Foundation.h> @interface DataModel : NSObject @property (strong) CLLocation *location; + (DataModel *)sharedModel; @end
DataModel.m
#import "DataModel.h" @class CLLocation; @implementation DataModel - (id) init { self = [super init]; if (self) { _location = nil; } return self; } + (DataModel *)sharedModel { static DataModel *_sharedModel = nil; static dispatch_once_t onceSecurePredicate; dispatch_once(&onceSecurePredicate,^ { _sharedModel = [[self alloc] init]; }); return _sharedModel; } @end
你需要#import "DataModel.h"
无论你需要它。 您可以将您的didUpdateLocations:
更改为:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { [locations lastObject]; [manager stopUpdatingLocation]; [DataModel sharedInstance].location = [locations lastObject]; }
从代码中的任何地方你都可以简单地通过[DataModel sharedInstance].location
来获取这个[DataModel sharedInstance].location
。
编辑:
对于一个非常简单的应用程序来说,这种方法可能看起来太过于夸张 但是,一旦你的应用程序增长,它肯定会得到回报使用它。
这种类/对象/单例是保存你的应用程序需要的所有数据(固定和临时)。 所以所有的数据源都可以很好地利用它。 简而言之:它使您能够轻松地遵循模型 – 视图 – 控制器的指导原则。
你当然冷用另一个类/对象/单例来保存临时数据 – 这取决于你的数据结构的复杂性。
您不必具体初始化这种对象。 它在你第一次参考时被初始化。 这就是为什么dispatch_once
。 它确保有这个共享对象的唯一的一个实例: https : //stackoverflow.com/a/9119089/653513
这个[DataModel sharedInstance]
单个实例将保留在那里,直到你的应用程序终止。
例如,Apple为[NSUserDefaults standardDefaults], [UIApplication sharedApplicaton]
使用类似的方法。
我倾向于将#import "DataModel.h"
放到我的项目Prefix.pch
所以我不必每次都使用它导入它(通过所有应用程序使用它)。
优点: – 数据在整个应用程序中可访问 – 代码可重用性 – MVC结构 – 代码更具可读性
缺点: – 我真的找不到一个。 除了dispatch_once(&onceSecurePredicate,^...
可能在头几秒混淆一个。
在didUpdateLocations
,您可以定义和设置本地variableslocation
,而不是在文件顶部定义的全局variableslocation
。 改变线
CLLocation *location = [locations lastObject];
至
location = [locations lastObject];
将解决这个问题。 但更好的解决scheme是在AppDelegate类中使用一个属性。 你可以在类扩展中定义它:
@interface AppDelegate () @property(strong, nonatomic) CLLocation *location; @end
然后你可以像实例方法那样访问它
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ [locations lastObject]; [manager stopUpdatingLocation]; self.location = [locations lastObject]; }
并在类似的方法
+(CLLocation *)getCurrentLocation{ // Get the instance: AppDelegate *app = [[UIApplication sharedApplication] delegate]; return app.location; }
更新:如果声明AppDelegate符合某些协议(在公共接口或类扩展中),例如:
@interface AppDelegate () <CLLocationManagerDelegate> @property(strong, nonatomic) CLLocation *location; @end
那么上面的代码会创build一个警告
initializing 'AppDelegate *__strong' with an expression of incompatible type 'id<UIApplicationDelegate>'
并明确的演员是必要的:
+(CLLocation *)getCurrentLocation{ // Get the instance: AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; return app.location; }
您可以使用[UIApplication sharedApplication].delegate
从应用程序的任何位置访问AppDelegate
,以便您可以:
CLLocation *location = [(YourAppDelegateClassName*)[UIApplication sharedApplication].delegate getCurrentLocation];
getCurrentLocation
方法需要是一个实例方法( -(CLLocation *)getCurrentLocation
)。 您还需要在需要使用该方法的文件中导入#import "YourAppDelegateClassName.h"
。
为了避免每次我在我的AppDelegates中实现一个静态方法的转换和访问[UIApplication sharedApplication].delegate
:
+ (YourAppDelegateClassName*)sharedDelegate { return (YourAppDelegateClassName*)[UIApplication sharedApplication].delegate; }
所以你可以使用这样的任何方法:
CLLocation *location = [[YourAppDelegateClassName sharedDelegate] getCurrentLocation];