如何在同步中获取位置管理器的共享实例

时间:2017-06-13 05:53:06

标签: objective-c cllocationmanager synchronized locationmanager background-task

Hy,我想获得后台位置更新,所以我编写了下面的代码并使其同步以保证其不受多线程的影响。所以我有两个问题:

  • 我是否真的需要同步这段代码,我在App中所做的只是运行后台任务?我从来没有创建任何特殊的NSThread类型来支持多线程,并且不需要这样做?

  • 每当我需要开始位置更新时,我都这样打电话:

    CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
    locationManager.delegate = self;
    [locationManager startUpdatingLocation];
    

    是正确的打电话方式吗?

    + (CLLocationManager *)sharedLocationManager {
    static CLLocationManager *_locationManager;
    @synchronized(self) {
        if (_locationManager == nil) {
    
            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
            [_locationManager requestAlwaysAuthorization];
            _locationManager.distanceFilter = 10;
    
            if(IS_OS_9_OR_LATER){
                _locationManager.allowsBackgroundLocationUpdates = YES;
            }
        }
    }
      return _locationManager;
    }
    

1 个答案:

答案 0 :(得分:1)

应同步共享实例。您可以使用@Synchronizeddispatch_once。即使您没有使用多个线程,也可以同步共享实例。

+ (instancetype)sharedLocationManager {

      static LocationTracker *sharedInstance_ = NULL;
      static dispatch_once_t onceToken;

      dispatch_once(&onceToken, ^{
        sharedInstance_ = [[LocationTracker alloc] init];
        [sharedInstance_ initialize];
     });

    return sharedInstance_;
}

- (void)initialize {
          _locationManager = [[CLLocationManager alloc] init];
          _locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
         [_locationManager requestAlwaysAuthorization];
          _locationManager.distanceFilter = 10;

         if(IS_OS_9_OR_LATER){
            _locationManager.allowsBackgroundLocationUpdates = YES;
         }
}

您可以在LocationTracker类中实现位置管理器委托。使用NSNotificationObserver更新所有期望更新位置的类。

另外,请按照以下行。

CLLocationManager *locationManager = [LocationTracker sharedLocationManager].locationManager;
locationManager.delegate = self;
[locationManager startUpdatingLocation];