В моем UIViewController initWithNibNameOrNil
я вызываю:
locationManager = [CLLocationManager new];
, чтобы создать объект, затем позже viewDidAppear
Я звоню:
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
Но я никогда не получаюобновление местоположения;менеджер местоположений никогда не начинает обновлять местоположение.Тем не менее, если я заменю ту же строку, initWithNibNameOrNil
на:
locationManager = [[myAppDelegate appDelegate] locationManager];
все будет отлично, за исключением случайных сбоев, иногда, когда
locationManager.delegate = self;
установлен в очень следующая строка после того, как менеджер местоположения установлен на уже назначенного менеджера в делегате приложения.Ничто из этого не имеет смысла для меня;Я не понимаю, почему одно отличается от другого, тем более, что ни один из них не работает последовательно.Может кто-нибудь, пожалуйста, просветите меня?
Резюме:
Метод 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];
}
Примечания. Используя этот метод создания менеджера местоположений,службы определения местоположения никогда не включаются после вызова startUpdatingLocation в viewDidAppear, поэтому обновления местоположения никогда не принимаются.
Метод 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, затем выталкиваю его, нажимаю его снова, выталкиваю его снова, затем пытаюсь подтолкнуть его снова, я получаю сбой каждый раз в строке в initWithNib ... где я устанавливаю для делегата значение self;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
, и я не получаю никаких сбоев после повторного нажатия / выталкивания контроллера представления.Это замечательно, но я не люблю выделять в viewDidAppear
, потому что приложение отстает на мгновение, потому что (я думаю) выделение locationManager забивает основной поток на это время.Я просто не понимаю, почему метод 1 вообще не работает, метод 2 падает, а метод 3 работает.Разве они все не делают более или менее одно и то же?
Извините за весь код, и поздравляю всех, кто прошел весь этот лабиринт вопроса!:)