【问题标题】:Best Practice using an Array of Strings with NSUserDefault使用带有 NSUserDefault 的字符串数组的最佳实践
【发布时间】:2015-08-12 13:44:00
【问题描述】:

我在将字符串数组保存到 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)
    }
}

当我运行它时,我得到:

致命错误:在展开可选值时意外发现 nil

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

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

【问题讨论】:

  • Optionals 是 Swift 语言的一个基本原则,我想你可以对read up on how they work 做。另外,这个问题在 Stack Overflow 上被问过很多次,例如:stackoverflow.com/q/24643522/429427(提示:当您在上面调用insert(_:atIndex:) 时,suggestions 看起来就像 nil

标签: arrays swift nsuserdefaults optional


【解决方案1】:

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

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 中建议的方式。

  • 如果尚未写入任何值,则读取默认值(空数组)。
  • 如果有值,则读取实际值

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

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:

【讨论】:

    【解决方案2】:

    嘿,就这样试试吧。

    var suggestions: [String] = Array() {
    
            didSet {
                var arrayEnd = suggestions.count
                if arrayEnd >= 5 {
                    arrayEnd = 4
                }
                if arrayEnd > 0
                {
                let newArray = Array(suggestions[0...(arrayEnd-1)])
                userDefaults.setObject(newArray, forKey: "suggestions")
                userDefaults.synchronize()
    
    
                }
    
            }
    
        }
    
    
        func getSuggestionData() {
            if userDefaults.valueForKey("suggestions") != nil {
                self.suggestions = userDefaults.objectForKey("suggestions") as! Array
            }
        }
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            getSuggestionData()
    
            if self.suggestions.count > 4
            {
                var str = "\(self.suggestions.count)"
                self.suggestions.insert(str, atIndex: self.suggestions.count)
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多