Не удается выделить CLLocationManager - PullRequest
0 голосов
/ 11 декабря 2011

В моем 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 работает.Разве они все не делают более или менее одно и то же?

Извините за весь код, и поздравляю всех, кто прошел весь этот лабиринт вопроса!:)

Ответы [ 3 ]

1 голос
/ 04 января 2012

Оказывается, виновником был невинный, казалось бы, кусок кода, который отключал менеджер местоположения сразу после его запуска. Единственная причина, по которой я это увидел, заключалась в том, что я сравнил проект с недавней резервной копией и заметил разницу. Другая проблема решена из-за резервного копирования!

1 голос
/ 11 декабря 2011

Попробуйте:

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

вместо нового.Вы уверены, что назначаете делегата как самого себя?В противном случае ваш класс не будет прослушивать обновления местоположения.

0 голосов
/ 21 февраля 2013

Тщательно, когда вы определяете свой менеджер местоположения.При использовании ARC может случиться так, что ваш экземпляр менеджера местоположений будет отброшен.

...