arrays - 将字符串数组与 NSUserDefault 结合使用的最佳实践

标签 arrays swift nsuserdefaults option-type

我在将字符串数组保存到 userDefaults 时遇到了一些问题。我有一个在类中声明的字符串数组,带有一个属性观察器以同步到 userDefaults。此外,我希望将数组限制为最多 5 个字符串。

let userDefaults = NSUserDefaults.standardUserDefaults()

var suggestions: [String]! {
    didSet {
        var arrayEnd = suggestions.count
        if arrayEnd >= 5 {
            arrayEnd = 4
        }
        let newArray = Array(suggestions[0...arrayEnd])
        userDefaults.setObject(newArray, forKey: "suggestions")
        userDefaults.synchronize()
    }
}

func getSuggestionData() {
    if userDefaults.valueForKey("suggestions") != nil {
        self.suggestions = userDefaults.valueForKey("suggestions") as? [String]
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    getSuggestionData()
    suggestions.insert("someString", atIndex: 0)
    }
}

当我运行它时,我得到:

fatal error: unexpectedly found nil while unwrapping an Optional value

在我尝试向数组插入新对象的那一行。 我已经尝试按照此线程中的方法进行操作,但它没有将任何内容保存到列表中。

我是 swift 的新手,可选类型不是我的强项,也许有人知道出了什么问题?

最佳答案

由于读取用户默认值可能会返回 nil 值,因此使用可选绑定(bind)是安全的:

func getSuggestionData() {
  if let suggestionArray = userDefaults.objectForKey("suggestions") {
    self.suggestions = suggestionArray
  } else {
    self.suggestions = [String]()
  }
}

但我建议使用具有已定义默认值的非可选变量。

在您应用的 AppDelegate 中,覆盖 init() 或插入代码以注册键/值对。

override init()
{
  let defaults = NSUserDefaults.standardUserDefaults()
  let defaultValue = ["suggestions" : [String]()];
  defaults.registerDefaults(defaultValue)
  super.init()
}

注册默认键和值是 Apple 在 documentation 中建议的方式.

  • 如果还没有写入值,则读取默认值(空数组)。
  • 如果有值,则读取实际值

代替变量的值观察器建议实现一个方法来插入一个新值,删除最后一个值并将数组写入磁盘。 无需使用可选绑定(bind),因为用户默认值中的数组始终具有已定义的状态。

let userDefaults = NSUserDefaults.standardUserDefaults()
var suggestions = [String]()

func insertSuggestion(suggestion : String)
{
  if suggestions.count == 5 { suggestions.removeLast() }
  suggestions.insert(suggestion, atIndex: 0)
  userDefaults.setObject(suggestions, forKey: "suggestions")
  userDefaults.synchronize()
}

func getSuggestionData() {
  suggestions = userDefaults.objectForKey("suggestions") as! [String]
}

override func viewDidLoad() {
  super.viewDidLoad()
  getSuggestionData()
  insertSuggestion("someString")
}

旁注:
如果您不需要明确的键值编码方法,请不要使用 valueForKey: 而不是 objectForKey:

关于arrays - 将字符串数组与 NSUserDefault 结合使用的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31967032/

相关文章:

java - 值仅返回0

javascript - 将一个数组插入另一个数组

ios - 如何在 Objective-C 中使用存储属性

ios - NSUserDefaults 与 UISegmentedControl

java - 将字符串数组转换为 Map

javascript - 每次用户单击按钮时,我都需要 Javascript 数组中的下一个值

ios - 特定特征的 BLE ReadValue 抛出 "Resource Insufficient Error"

swift - 关闭 RestKit Swift 中的 WAL 文件模式

ios - NSUserDefaults 还是后端?

ios - 在 NSUserDefaults 中设置默认设置。我做错了什么?