将 stopUpdatingLocation 发送到 CLLocationManager 后,NSUserDefaultsDidChangeNotification 不会触发

Posted

技术标签:

【中文标题】将 stopUpdatingLocation 发送到 CLLocationManager 后,NSUserDefaultsDidChangeNotification 不会触发【英文标题】:NSUserDefaultsDidChangeNotification Doesn't Fire After Sending stopUpdatingLocation to CLLocationManager 【发布时间】:2014-01-28 17:43:16 【问题描述】:

目前在这个 ios 应用程序中,我添加了一些我作为观察者编写的控制器到 [NSNotificationCenter defaultCenter] 以观察 NSUserDefaultsDidChangeNotification

- (void)startObservingDefaults

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(userDefaultsDidChange)
                                                 name:NSUserDefaultsDidChangeNotification
                                               object:nil];

我正在观看的用户默认设置应使用设置菜单中的PSToggleSwitchSpecifier 启用或禁用CLLocationManager。启动应用程序并将startUpdatingLocation 发送到CLLocationManager ivar 后,我可以转到设置菜单并禁用位置管理器。然后我的选择器userDefaultsDidChange 将检查该默认设置是启用还是禁用。如果启用,我发送startUpdatingLocation 到位置管理器实例,如果它被禁用,我发送stopUpdatingLocation 给它。每条路径都像这样记录它的动作

- (void)userDefaultsDidChange

    if ([self duringOperationHours] && [self isEnabled]) 
        NSLog(@"\n\n\nWithin Operating Hours.\n\n\n");
        [_locationManager startUpdatingLocation];
        NSLog(@"Enabled Location Manager.");
     else 
        NSLog(@"\n\n\nDisabled or Outside of Operating Hours.\n\n\n");
        [_locationManager stopUpdatingLocation];
        NSLog(@"Disabled Location Manager.");
    

我还有其他控制一天中时间的设置(开始时间和结束时间,例如早上 6 点到下午 6 点)。如果我更改其中一项设置并且当前时间仍在该时间范围内,则日志将显示它仍处于“工作时间内”。并且启用了位置管理器。

如果我更改它以禁用位置管理器,它会在我上面的方法中记录NSLog 语句并且它确实关闭位置管理器。

当我尝试重新启动它时,问题就来了。所以说我在设置中并且它已启用。我禁用它,日志显示它被禁用并且 GPS 的小图标消失,如果我然后重新启用它,通知根本不会触发。事实上,在我返回应用程序之前,即使在其他子窗格中也不会触发其他设置。 (我在 userDefaultsDidChange 方法中对 main_queue 和 global_queue 都尝试了 dispatch_async 并没有看到任何变化)。

我的问题是我是否做错了可能导致位置管理器锁定的问题?或者这是 CLLocationManager 的一些内部队列问题?或者是其他东西?也许CLLocationManager 只有在应用程序在前台时才会启动?即使是这种情况,我应该仍然看到它至少尝试启动位置管理器的日志语句对吗?

【问题讨论】:

【参考方案1】:

没关系,我想通了。

观察NSUserDefaultsDidChangeNotification 上的NSNotificationCenter 不会唤醒应用程序。正在发生的事情是应用于我的控制器的CLLocationManagerDelegate 协议将“唤醒”应用程序以使用接收到的CLLocations 执行所需的操作。醒来后,观察到 NSNotificationCenter 中某些用户默认值的更改将触发我的选择器 userDefaultsDidChange

只要CLLocationManager 正在更新并在那里提醒应用程序,它将允许控制器调用指定的选择器。当 CLLocationManager 不再更新位置时,应用程序不会被唤醒,因此在应用程序返回前台之前不知道任何用户默认值已更改。

如果我为这个奇怪的观察场景想出更好的解决方案,我会更新这个答案。

【讨论】:

抱歉撞了。你想清楚了吗?我也有同样的情况……谢谢。 这就是答案。 NSNotificationCenter 通知不会为该特定事件唤醒应用程序。 CLLocationManager 正在唤醒应用程序并允许接收通知。关闭后,您必须将应用程序带回前台才能接收事件。

以上是关于将 stopUpdatingLocation 发送到 CLLocationManager 后,NSUserDefaultsDidChangeNotification 不会触发的主要内容,如果未能解决你的问题,请参考以下文章

CoreLocation:LocationManager.stopUpdatingLocation() 不工作

locationManager requestLocationUpdates 和 stopUpdatingLocation 之间有啥区别?

即使我调用 stopUpdatingLocation 仍然显示位置管理器图标

stopUpdatingLocation 在 iOS 7 中不起作用

CLLocationManager stopUpdatingLocation 不会停止

如何使定位服务图标从状态栏中消失?