Два CLlocationManager се намесват

Имам две CLLocationManage в рамките на приложение. Първият е за наблюдение на регионите за маяк, докато другият е за наблюдение на нормалния CLRegion.

Първият в A.m

// Do any additional setup after loading the view.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;

Втори в Б.м

  gpsLocationManager = [[CLLocationManager alloc] init];
  gpsLocationManager.delegate = self;

За последното съм почти сигурен, не съм извикал никакъв startMonitoringForRegion за нито един регион на маяк. Изглежда обаче, че gpsLocationmanager в B продължава да получава обратното извикване enterRegion от този в A. Така че завършва с моята проверка на параметъра на предадения регион, за да накарам gpsLocationManager да не отговаря на никакво обратно извикване от въвеждане на регион на маяк.

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
  NSLog(@"%d regions under monitor:", self.gpsLocationManager.monitoredRegions.count);
  NSLog(@"%d regions in regionArray:", self.regionArray.count);
  NSLog(@"Region type %@:", [region class]);
 if(![region isKindOfClass:[CLBeaconRegion class]]){

Някаква идея?

Поздрави Хамър


person Hammer    schedule 10.11.2014    source източник
comment
Би ли помогнал сингълтън в този случай? Статичен екземпляр на мениджъра на местоположението, който съществува по време на изпълнение на приложението. По този начин имате само 1 мениджър на местоположения. В противен случай може би можете да имате булев флаг, за да идентифицирате дали трябва да отговаря на актуализация на местоположението.   -  person Zhang    schedule 10.11.2014
comment
Благодаря. Всъщност се опитвах да използвам singleton. Въпреки това, тъй като моето наблюдение е върху различни категории, които са настроени да бъдат с различна точност, честота, дори типовете региони тук. Променям обратно двата подхода на CLLocationmanager в края. Да, решението ви е добро, но само малко любопитно защо се случва докладваният проблем, тъй като използвам два различни екземпляра.   -  person Hammer    schedule 10.11.2014


Отговори (3)


Функционалността на CoreLocation се предоставя на базата на цялото приложение.

Ето защо общият модел е да инициализирате вашия CLLocationManager във вашия AppDelegate и да го направите CLLocationManagerDelegate.

Ако имате нужда от достъп до вашия един CLLocationManager в множество UIViewControllers, бих го направил собственост на вашия AppDelegate. След това можете да препратите обратните извиквания, от които се нуждаете, към UIViewControllers, ако са били инициализирани и са видими.

person davidgyoung    schedule 10.11.2014
comment
Проблемът за мен е, че имам различни видове региони. Някои региони се нуждаят от нормална актуализация с добра точност като kCLLocationAccuracyBest, докато някои се нуждаят от актуализация на значителна промяна с точност като kCLLocationAccuracyKilometer и т.н. За този сценарий е трудно всичко да се направи в един мениджър на местоположения. - person Hammer; 11.11.2014
comment
Днес опитах отново и открих още една интересна констатация. Мениджърът на местоположението в A.m, който наблюдава региона на маяка, също получава напускането на региона, задействано от географския регион, наблюдаван в мениджъра на местоположение в B.m. Правя още един опит да създам C.m с друг locationManger, за да наблюдавам географски регион. Не пречи на този в Б.м. Засега това изглежда се случва само в случаите, когато единият наблюдава регион на маяк, а другият наблюдава географски регион. - person Hammer; 11.11.2014

Сблъсках се със същия проблем, когато създадох 2 класа (1 за Geo Fencing (CLRegion или CLCircularRegions) и 2 за Beacon REgions (CLBeaconRegions). И двата са единични класове със свойството, наречено lManager(CLLocationManager).

първоначално опитах с тази условна проверка

if (manager == self.gpsLocationManager) {
  // Do things 
}

както каза Уилмар. Не работи..

след задълбочено проучване на регионалните класове, използвах по-долу условие за промяна на регионите. ПРИМЕР:

func locationManager(manager: CLLocationManager!, didStartMonitoringForRegion region: CLCircularRegion!) {

      if(region.isMemberOfClass(CLCircularRegion)){
    // Do things. here 
 }
}

При мен работи.

Наздраве :p

person Community    schedule 29.03.2015

Във вашите A.m и B.m можете да проверите дали LocationManager, който отговаря, е LocationManager, който ви интересува, и да реагирате съответно. Въпреки това бих се опитал да се придържам към единичен LocationManager, както беше споменато от davidgyoung.

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    if (manager == self.gpsLocationManager) {
        // do things
    }
    else {
        // this is another location manager which I am not interested in
    }
}
person Wilmar    schedule 10.11.2014
comment
Не трябва ли делегатът просто да използва правилния екземпляр? Със сигурност вашето решение ще работи само ако един и същ делегат се използва за множество екземпляри на мениджър на местоположение? - person trojanfoe; 10.11.2014
comment
@trojanfoe Съгласен съм с това, което казваш. Просто направихме предложението за проверката, тъй като нямаме пълния контекст на кода. - person Wilmar; 11.11.2014
comment
това беше, което опитах на първо място и не реши проблема - person Hammer; 11.11.2014