【问题标题】:NSUserDefaults and KVO issuesNSUserDefaults 和 KVO 问题
【发布时间】:2011-08-08 12:30:29
【问题描述】:

我在我的应用程序中使用 NSUserDefaults,我希望在更改特定值时收到通知。为此,我在 viewDidLoad 中添加了以下几行:

NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
[settings synchronize];
[settings addObserver:self forKeyPath:@"pref_server" options:NSKeyValueObservingOptionNew context:NULL];

以及要通知的方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{

    NSLog(@"Change");

    NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
    if (object == settings && [keyPath isEqualToString:@"pref_server"])
    {
        NSLog(@"Server did change");
    }

}

不幸的是,后者永远不会被调用...@“pref_server”是我在 Root.plist 中设置的项目标识符,在 Settings.bundle 中。我做错了什么?

【问题讨论】:

  • 在一个有点不相关的注释中,synchronise() 的文档指出:“等待对默认数据库的任何挂起的异步更新并返回;此方法是不必要的,不应使用。”跨度>
  • 如果遇到问题,请查看 NSUserdefaults 的作者之一的这篇非常详细的博客文章:dscoder.com/defaults.html

标签: ios


【解决方案1】:

我建议使用适当的通知:NSUserDefaultsDidChangeNotification

在 Xcode 的 Apple 文档中搜索 AppPrefs,它会显示一个示例应用程序,该示例应用程序完全符合您的要求。只需编译并运行!它使用NSUserDefaultsDidChangeNotification

这是用于注册观察者的代码:

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

【讨论】:

  • 对于 Swift3:NotificationCenter.default.addObserver(self, selector: #selector(defaultsChanged), name: UserDefaults.didChangeNotification, object: nil)
  • 如果更改发生在另一个进程中,则不会发送通知,因此 KVO 是检查主应用程序及其扩展之间共享的 NSUserDefaults 键值更改的唯一方法(今日小部件等)
【解决方案2】:

NSUserDefaults 不兼容 KVO,但 NSUserDefaultsController 是。所以你会使用:

NSUserDefaultsController *defaultsc = [NSUserDefaultsController sharedUserDefaultsController];
[defaultsc addObserver:self forKeyPath:@"values.pref_server" 
               options:NSKeyValueObservingOptionNew 
               context:NULL];

【讨论】:

【解决方案3】:

有趣的观察:

[NSUserDefaults standardUserDefaults] 现在似乎符合KVO 标准,因为我能够观察并绑定到它的值。我正在运行 10.7.2,使用 Xcode 4.2, SDK 10.7, LLVM compiler 3.0

我似乎在发行说明的任何地方都找不到这种新行为的记录。

【讨论】:

  • 我认为这是 Lion 中未记录的更改。发行说明提到了对默认值的一些更改,所以我猜 KVO 支持同时发生了变化。 Snow Leopard 和 Lion 的 Cocoa Bindings Programming Topics 中记录了对 KVC/KVO 使用控制器的需求。
  • 这个问题专门针对ios
  • 文档声明它是合规的:“...您可以使用键值观察来通知特定默认值的任何更新...”:developer.apple.com/documentation/基础/用户默认值
【解决方案4】:

虽然没有很好的文档记录,但 NSUserDefaults 在 iOS7 中确实支持键值观察。

【讨论】:

    【解决方案5】:

    从 iOS 11.3 开始,这可以工作并记录在案:

    响应默认值更改

    您可以使用键值观察来获得对特定默认值的任何更新的通知。

    【讨论】:

      猜你喜欢
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多