【问题标题】:UserDefaults between Objective-C and SwiftObjective-C 和 Swift 之间的 UserDefaults
【发布时间】:2017-10-25 13:44:38
【问题描述】:

只是在这里要格外小心......

如果我有一个应用程序在 Objective-C 中像这样在 UserDefaults 中保存了一个值:

NSString *newString = textField.text;
[[NSUserDefaults standardUserDefaults] setObject: newString forKey:@"textKey"];

当我发布对现在以 Swift 编码的应用程序的更新时,这是否是检查此值是否存在的正确方法:

if (UserDefaults.standard.object(forKey: "textKey") as? String) != nil {
     print("There is a string")
} else {
     print("No string exists") 
}

我尝试使用 .string(forKey:) 和 .bool(forKey:) ,因为它们已经被引入,但是它是最安全的,因为它被保存为一个对象,将它作为一个对象拉出来,然后用它测试它“作为?字符串”?

同一问题的棘手版本:

NSDictionary 对象的 NSMutableArray 被保存为 UserDefaults 中的对象

if let oldData = UserDefaults.standard.object(forKey: "theData") as? [NSMutableDictionary] {

}

NSDictionary 和 NSMutableDictionary 在这里可以互换吗?

谢谢!

【问题讨论】:

    标签: objective-c swift string object userdefaults


    【解决方案1】:

    [NS]UserDefaults 由 plist 和字典支持。 Objective-C 字符串作为 <string>Some Text</string> 保存到 plist。

    在 Swift 中加载的同一个 plist 为该键提供了一个字符串。

    所以使用UserDefaults.string 读取Objective-C 存储的值应该没有问题。当然,您仍然需要验证该值是否确实存在。

    if let str = UserDefaults.standard.string(forKey: "textKey") {
        print("Found \(str)")
    } else {
        print("No string for key")
    }
    

    即使原始值不是字符串,使用UserDefault.string 也是安全的。对于非字符串值,它将简单地返回 nil

    关于NSDictionaryNSMutableDictionary,注意UserDefaults 只检索不可变的NSDictionary。您无法从UserDefaults 读取NSMutableDictionary(或数组)。

    请注意,您可以安全地使用 Swift 字典来阅读原始 NSDictionary。无需使用 Objective-C 类。

    【讨论】:

    • 可以从 UserDefaults 读取一个数组,并且无论我使用 if let oldData = UserDefaults.standard.object(forKey: " theData") 作为? [NSMutableDictionary] { } 或者如果让 oldData = UserDefaults.standard.object(forKey: "theData") as? [NSDictionary] { }。正如您所提到的,这些是不可变的 Dictionary 对象。
    • 我没有说你不能加载数组。我说它们是不可变的。并且没有理由使用 Objective-C 类。将字典直接加载到 Swift 字典中。
    • 将此答案标记为正确。如果我添加这些通用参数,我可以使用 Swift 'Dictionary' 作为数组中对象的值类型: if let oldData = defaults.object(forKey: "theData") as? [字典] { }
    【解决方案2】:

    是的,您的解决方案是安全的,如果您在 Objective C 代码中保存的值确实是 String 类型,那么当您从 NSUserDefaults 检索该值时,它将是一个字符串,并且将正确地强制转换为Swift 代码的 ? 运算符的字符串。

    【讨论】:

      【解决方案3】:

      推荐的方式(在 Swift 和 Objective-C 中)是为 register 每个键值对提供一个默认值。在第一次更改该值之前,会一直考虑此默认值。

      let userDefaults = UserDefaults.standard
      let defaultValues : [String : Any] = ["textKey" : "", "dictionaryKey" : [:]]
      userDefaults.register(defaults: defaultValues)
      

      现在你可以放心地写了

      if UserDefaults.standard.string(forKey: "textKey")!.isEmpty {
           print("No string exists") 
      } else {
           print("There is a string")
      }
      

      当然,开发者负责覆盖具有相同类型的值。


      NSMutableDictionary 与 Swift Dictionary 无关。要获取可变对象,只需使用 var 关键字。

      var dictionary = UserDefaults.standard.object(forKey: "dictionaryKey") as! [String:Any]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-11
        • 2018-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-10
        相关资源
        最近更新 更多