【问题标题】:iPhone - How to detect if a key exists in NSUserDefaults standardUserDefaultsiPhone - 如何检测 NSUserDefaults standardUserDefaults 中是否存在密钥
【发布时间】:2011-07-20 19:42:44
【问题描述】:

使用NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];,

我使用像 BOOL boolFromPrefs = [defaults boolForKey:@"theBoolKey"]; 这样的调用来获取保存的 BOOL 值。

如果未找到密钥,则返回 NO(boolForKey 的默认行为)。
但是... NO 可以是已保存的设置。 intForKey也一样

那么在尝试获取它的值之前,我如何测试一个键是否存在?

【问题讨论】:

    标签: iphone cocoa-touch nsuserdefaults preferences key-value


    【解决方案1】:

    以正确的方式做事并register default values。

    NSDictionary *userDefaultsDefaults = @{
        @"SomeKey": @NO,
        @"AnotherKey": @"FooBar",
        @"NumberKey": @0,
    };
    [NSUserDefaults.standardUserDefaults registerDefaults:userDefaultsDefaults];
    

    在使用 NSUserDefaults 中的任何内容之前执行此操作。 application:didFinishLaunchingWithOptions: 的开头是一个安全的地方。

    您必须在每次应用启动时注册默认设置。 NSUserDefaults 仅存储已明确设置的值。

    如果您使用默认值,则不必像其他答案中建议的那样检查“isFirstLaunch”键。
    这将在您推出更新并且想要更改 NSUserDefaults 项目的默认值时为您提供帮助。

    【讨论】:

    • 我确实认为这是一个有价值的选择,但我也可以看到不注册默认值也有好处。它为您提供了三元逻辑,您可以在其中判断用户是否明确将其设置为是或否,或者没有全部设置。
    • 我不确定,但我认为这种做法在第一个 1.0 版本中效果很好。如果稍后您的偏好层次结构发生重大变化,您可能需要知道写了什么,没有写什么,以重新分配整个内容。可能......或者也许在文件中包含一个 Prefs 版本就足够了。我不知道,我正在为此努力,以防止将来旧的首选项文件出现一些问题。你知道一个很好的阅读来源吗?
    • 这些默认值不会写入 NSUserDefaults(这就是为什么您必须在每次启动时注册它们),当您希望在以后的版本中使用新的默认值时,只需注册新的默认值即可。如果用户从未接触过设置,则使用新的默认设置,如果他更改了设置,他很可能还是想使用自己的设置。
    • 你好。我试着按照你的方式做。在保存默认首选项时存在一些问题。你能看看这个问题吗? stackoverflow.com/questions/5439328/…
    • @MatthiasBauch “每次应用启动时您都必须注册默认值”?为什么 ?我只需要在应用程序首次启动时注册一次默认值!
    【解决方案2】:

    在转换为 BOOL 之前检查对象是否存在。

    if ([defaults objectForKey:@"theBoolKey"] != nil) {
        boolFromPrefs = [defaults boolForKey:@"theBoolKey"];
    } else {
        boolFromPrefs = DEFAULT_BOOL_VALUE;
    }
    

    【讨论】:

    • @phatmann 为什么会这样? afaik,如果未设置 ObjectForKey 将返回 nil,如果为 false,则返回 0,如果为 true,则返回 1。
    • @Pega88 我在以前的 iOS 版本中肯定遇到了这种方法的问题,其他人也注意到了同样的问题。事实上这就是我搜索stackoverflow的原因。我不知道这种行为在最新的操作系统中是否发生了变化,以及它发生的确切条件是什么。
    • @phatmann 我认为它对你不起作用的原因是你的代码中使用了 boolForKey ,而不是 objectForKey 。
    【解决方案3】:

    我是这样做的:

    NSUserDefaults *prefs = NSUserDefaults.standardUserDefaults;
    if ([[prefs dictionaryRepresentation].allKeys containsObject:@"yourKey"]) {
      float yourValue = [prefs floatForKey:@"yourKey"];
    }
    

    【讨论】:

    • 这是最佳解决方案,因为该值可能等于 0,因此评估返回的值可能不正确。
    • 我担心性能。每次将用户默认值转换为字典需要时间吗?
    【解决方案4】:

    您可以使用objectForKey: 进行测试,如果为 nil 则未设置。所有 boolForKey 都会接受返回的 NSNumber(如果有)并返回 BOOL 值。

    【讨论】:

    • MonoTouch 用户注意:ObjectForKey(key) 方法不可访问,因为它被标记为内部。相反,请使用索引器:NSUserDefaults.StandardUserDefaults[key]。
    【解决方案5】:

    我建议为您的应用程序可能使用的任何键设置默认值。您可以在 application:didFinishLaunchingWithOptions: 方法中执行此操作。这样您就会知道每个值都已设置。

    提示,将名为“defaultsSet”的键设置为 YES,以便您只执行一次。另外,记得调用 [[NSUserDefaults standardUserDefaults] synchronize] 来保存值。

    【讨论】:

    • “将名为“defaultsSet”的键设置为 YES 以便您只执行一次”是什么意思?
    • 我建议作为一种确保默认设置只设置一次而不覆盖用户更改的方法。你可以称它为任何名称,它只是另一个设置为已知值的键。
    • 对不起,我可能累了,但我还是不明白你的意思。能给我举个例子吗?
    【解决方案6】:

    基于 MarkPowell 回答的 Swift 示例

    if (NSUserDefaults.standardUserDefaults().objectForKey("SomeBoolSetting") == nil) {
        NSUserDefaults.standardUserDefaults().setBool(true, forKey: "SomeBoolSetting")
        println("Bool WAS nil")
    } else {
        var boolValue:Bool? = NSUserDefaults.standardUserDefaults().boolForKey("SomeBoolSetting")
        println("Bool WAS NOT nil \(boolValue)")
    }
    

    【讨论】:

      【解决方案7】:

      @Tim Autin 答案的快速版本:

      if contains(NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys.array, "chuiser_cook_orders_dirty") {
          println("exist")
      } 
      

      【讨论】:

      • Swift 3 的语法更加简洁,将条件简化为:UserDefaults.standard.dictionaryRepresentation().keys.index(of: "chuiser_cook_orders_dirty") != nil
      【解决方案8】:

      不要复杂化:

      if([NSUserDefaults.standardUserDefaults  objectForKey:@"yourBoolKey"])
      {
        // Object Already Stored in User defaults
      }
      else
      {
         //Object not stored
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-30
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 2020-08-19
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        相关资源
        最近更新 更多