无法分配CLLocationManager

在我的UIViewController的initWithNibNameOrNil ,我打电话:

 locationManager = [CLLocationManager new]; 

创build对象,然后在viewDidAppear我稍后调用:

 [locationManager startUpdatingLocation]; [locationManager startUpdatingHeading]; 

但我从来没有收到位置更新; 位置pipe理员从不开始更新位置。 但是,如果我用同一行代替initWithNibNameOrNil

 locationManager = [[myAppDelegate appDelegate] locationManager]; 

一切工作很好,除了随机崩溃时有时

 locationManager.delegate = self; 

在位置pipe理器被设置为应用程序委托中的已经分配的pipe理器之后,被设置在下一行中。 这对我来说没有任何意义。 我不明白为什么一个人和另一个人不一样,更不用说为什么他们都不一致。 有人可以开导我吗?

概要:

方法1(不起作用):

MapView.m中

initWithNibNameOrNil

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if(self) { locationManager = [CLLocationManager new]; locationManager.delegate = self; locationManager.distanceFilter = kCLHeadingFilterNone; locationManager.headingFilter = 3; if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; else locationManager.desiredAccuracy = kCLLocationAccuracyBest; //more setup irrelevant to the question } return self; } 

viewDidAppear

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:YES]; [locationManager startUpdatingLocation]; [locationManager startUpdatingHeading]; } 

注意:使用这种创build位置pipe理器的方法,在viewDidAppear中调用startUpdatingLocation之后,定位服务从不会启用,因此不会收到位置更新。


方法2(主要工作):

myAppDelegate.m中

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; self.locationManager = [CLLocationManager new]; self.locationManager.distanceFilter = kCLHeadingFilterNone; self.locationManager.headingFilter = 3; if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; else self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; //more irrelevant setup } 

MapView.m中

 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if(self) { locationManager = [[Trail_TrackerAppDelegate appDelegate] locationManager]; locationManager.delegate = self; //more irrelevant setup } return self; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:YES]; [locationManager startUpdatingLocation]; [locationManager startUpdatingHeading]; } 

注意 :这种分配方法的作品,除非我推MapView,然后popup它,再次推,再次popup,然后再次推它,我每次在initWithNib行…我在哪里设置崩溃委托自己; NSZombieEnabled说:

 -[CLLocationManager setDelegate:]: message sent to deallocated instance 0x9540ad0 

有趣…

NSLog(@“%s:%@;%@”, PRETTY_FUNCTION ,self,locationManager)说:

 -[MapView initWithNibName:bundle:]: <MapView: 0x92ae3e0>; <CLLocationManager: 0x92a3560> 

方法3(全面工作):

MapView.m中

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:YES]; locationManager = [CLLocationManager new]; locationManager.delegate = self; locationManager.distanceFilter = kCLHeadingFilterNone; locationManager.headingFilter = 3; if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; else locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; [locationManager startUpdatingHeading]; } 

注意 :所有的分配和设置都是在viewDidAppear完成的,并且在重复推送/popup视图控制器后,我不会看到任何崩溃。 这是伟大的,但我不喜欢在viewDidAppear分配,因为应用程序滞后一会儿,因为(我认为)locationManager的分配堵塞了主线程的时间。 我真的不明白为什么方法1根本不起作用,方法2崩溃,方法3起作用。 难道他们不都是做同样的事吗?

对不起所有的代码,并祝贺任何人通过这个迷宫的问题! 🙂

尝试:

 locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; [self.locationManager startUpdatingLocation]; 

而不是新的。 你确定你把自己的代表分配给自己吗? 否则,你的class级将不会侦听位置更新。

原来,罪魁祸首是一个看似无辜的代码,一旦开始就closures了位置pipe理器。 我看到的唯一原因是因为我把这个项目和最近的一个备份进行了比较,发现了这个差异。 另一个问题,因为备份解决!

小心你在哪里定义你的位置经理。 使用ARC时,可能会发生您的位置pipe理器实例被丢弃。