无法分配CLLocationManager [英] Can't allocate CLLocationManager
问题描述
在我的UIViewController的 initWithNibNameOrNil
中,我叫:
locationManager = [CLLocationManager新];
创建对象,然后在 viewDidAppear
我叫:
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
但是我从未收到位置更新;位置管理器永远不会开始更新位置。但是,如果我将同一行替换为 initWithNibNameOrNil
:
locationManager = [[myAppDelegate appDelegate] locationManager];
一切正常,除了有时会偶然崩溃的情况
locationManager.delegate = self;
在位置管理器设置为非常后的下一行中设置已经在应用程序委托中分配了经理。这些对我来说都没有道理;我不明白为什么一个与另一个不同,更不用说为什么都不能始终如一地工作了。有人可以启发我吗?
摘要:
方法1(是否 not work):
在 MapView.m :
initWithNibNameOrNil
:
-(id)initWithNibName:(NSString * )nibNameOrNil捆绑包:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil捆绑包:nibBundleOrNil];
if(self){
locationManager = [CLLocationManager new];
locationManager.delegate =自我;
locationManager.distanceFilter = kCLHeadingFilterNone;
locationManager.headingFilter = 3;
if(([[[[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging)||([[[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull))
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
else
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//与问题
无关的更多设置}
return self;
}
viewDidAppear
:
-(void)viewDidAppear:(BOOL)动画{
[super viewDidAppear:YES];
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
}
注意:使用这种创建位置管理器的方法,永远不会启用位置服务在viewDidAppear中调用startUpdatingLocation之后,因此从未收到任何位置更新。
方法2(确实
在 myAppDelegate.m :
-(BOOL)应用程序:(UIApplication *)应用程序didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
self.locationManager = [CLLocationManager新];
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;
//更多不相关的设置
}
在 > MapView.m :
-(id)initWithNibName:(NSString *)nibNameOrNil捆绑包:(NSBundle *) nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self){
locationManager = [[Trail_TrackerAppDelegate appDelegate] locationManager];
locationManager.delegate =自我;
//更多不相关的设置
}
return self;
}
-(void)viewDidAppear:(BOOL)动画{
[super viewDidAppear:YES];
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
}
注意:此分配方法有效,除非我按下MapView,然后弹出它,再次按下它,再次弹出它,然后尝试再次按下它,每次在initWithNib中的行上都发生崩溃...我将委托设置为self; NSZombieEnabled
说:
-[CLLocationManager setDelegate:]:消息发送至释放实例0x9540ad0
有趣的事情...
NSLog(@%s:%@;%@, PRETTY_FUNCTION ,self,locationManager)说:
-[MapView initWithNibName:bundle:]:< MapView:0x92ae3e0> ;; < CLLocationManager:0x92a3560>
方法3(全面运行):
在 MapView.m 中:
-(void)viewDidAppear:(BOOL)动画{
[super viewDidAppear:YES];
locationManager = [CLLocationManager新];
locationManager.delegate =自我;
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
中完成,在反复推送/弹出视图控制器后我没有崩溃。这很棒,但是我不喜欢在 viewDidAppear
中分配,因为应用程序滞后了片刻,因为(我认为)locationManager的分配阻塞了该主线程时间。我只是真的不明白为什么方法1根本不起作用,方法2崩溃了,方法3起作用。
对不起,所有代码都对不起,并祝贺在这种迷宫中一路走来的所有人一个问题! :)
原来,罪魁祸首是看似无害的一段代码,该代码一经关闭便关闭了位置管理器。正在开始。我看到它的唯一原因是因为我将项目与最近的备份进行了比较,并注意到了差异。由于备份,另一个问题得以解决!
In my UIViewController's initWithNibNameOrNil
, I call:
locationManager = [CLLocationManager new];
to create the object, then later in viewDidAppear
I call:
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
But I never receive a location update; the location manager never starts updating the location. Yet if I replace that same line the initWithNibNameOrNil
with:
locationManager = [[myAppDelegate appDelegate] locationManager];
everything works great, except for random crashes sometimes when
locationManager.delegate = self;
is set in the very next line after location manager is set to the already allocated manager in the app delegate. None of this makes sense to me; I don't understand why one is different from the other, much less why neither of them works consistently. Can someone please enlighten me?
Summary:
Method 1 (does not work):
In 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];
}
Notes: Using this method of creating the location manager, location services never get enabled after startUpdatingLocation is called in viewDidAppear and so no location updates are ever received.
Method 2 (does work, mostly):
In 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
}
In 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];
}
Notes: this allocation method works, except if I push MapView, then pop it, push it again, pop it again, then try to push it again, I get a crash every time at the line in initWithNib... where I set the delegate to self; NSZombieEnabled
says:
-[CLLocationManager setDelegate:]: message sent to deallocated instance 0x9540ad0
Interesting...
NSLog(@"%s: %@; %@", PRETTY_FUNCTION, self, locationManager) says this:
-[MapView initWithNibName:bundle:]: <MapView: 0x92ae3e0>; <CLLocationManager: 0x92a3560>
Method 3 (works all-around):
In 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];
}
Notes: all of the allocation and setup is done in viewDidAppear
, and I don't get any crashes after repeated pushing/popping of the view controller. This is great, but I don't like allocating in viewDidAppear
because the app lags for just a moment because (I think) the allocation of locationManager clogs up the main thread for that time. I just really don't understand why Method 1 doesn't work at all, Method 2 crashes, and Method 3 works. Don't they all do more-or-less the same thing?
Sorry for all the code, and congrats to anyone who made it all the way through this maze of a question! :)
Turns out the culprit was a seemingly-innocent piece of code that was turning off the location manager as soon as it was being started. The only reason I saw it was because I compared the project to a recent backup, and noticed the difference. Another problem solved because of backing up!
这篇关于无法分配CLLocationManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!