[英]method not called from app delegate in 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;
}
將其更改為帶有“-”的實例方法無效。 是否應將“位置”設置為實例? 應該將委托設為實例,還是有更好的方法從其他地方訪問它?
在didUpdateLocations
,您可以定義和設置本地變量location
,而不是在文件頂部定義的全局變量location
。 換線
CLLocation *location = [locations lastObject];
至
location = [locations lastObject];
將解決問題。 但是更好的解決方案是在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
然后上面的代碼創建一個警告
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;
}
Martin的答案是以一種與您的方法一致的方式來解決此問題的有效快捷方法-將位置存儲在appDelegate
。
如果要更進一步,則可能需要考慮實現一個保存數據的特殊對象-數據模型。 將數據存儲在應用程序委托中被認為是一種不好的做法-這不是它的用處(盡管它在示例或小型應用程序中工作得很好)。
您可以執行以下操作:
數據模型
#import <Foundation/Foundation.h>
@interface DataModel : NSObject
@property (strong) CLLocation *location;
+ (DataModel *)sharedModel;
@end
數據模型
#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]
例如[NSUserDefaults standardDefaults], [UIApplication sharedApplicaton]
使用類似的方法。
我傾向於將#import "DataModel.h"
放入我的項目Prefix.pch
這樣我就不必每次使用它時都將其導入(通過所有應用程序使用)。
優點:-整個應用程序均可訪問數據-代碼可重用性-MVC結構-代碼更具可讀性
缺點:-我找不到一個。 除了dispatch_once(&onceSecurePredicate,^...
可能會在前幾秒鍾使一個混淆。
您可以使用[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];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.