将 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
协议将“唤醒”应用程序以使用接收到的CLLocation
s 执行所需的操作。醒来后,观察到 NSNotificationCenter
中某些用户默认值的更改将触发我的选择器 userDefaultsDidChange
。
只要CLLocationManager
正在更新并在那里提醒应用程序,它将允许控制器调用指定的选择器。当 CLLocationManager 不再更新位置时,应用程序不会被唤醒,因此在应用程序返回前台之前不知道任何用户默认值已更改。
如果我为这个奇怪的观察场景想出更好的解决方案,我会更新这个答案。
【讨论】:
抱歉撞了。你想清楚了吗?我也有同样的情况……谢谢。 这就是答案。 NSNotificationCenter 通知不会为该特定事件唤醒应用程序。 CLLocationManager 正在唤醒应用程序并允许接收通知。关闭后,您必须将应用程序带回前台才能接收事件。以上是关于将 stopUpdatingLocation 发送到 CLLocationManager 后,NSUserDefaultsDidChangeNotification 不会触发的主要内容,如果未能解决你的问题,请参考以下文章
CoreLocation:LocationManager.stopUpdatingLocation() 不工作
locationManager requestLocationUpdates 和 stopUpdatingLocation 之间有啥区别?
即使我调用 stopUpdatingLocation 仍然显示位置管理器图标
stopUpdatingLocation 在 iOS 7 中不起作用