stringForKey崩溃App

时间:2014-11-18 09:59:24

标签: ios swift nsuserdefaults

我正在尝试在NSUserDefaults中存储一个字符串,但是当我去检索它时,我的应用程序崩溃了。

我认为这只是第一次发生,因为在NSUserDefaults中从未为该键设置过值,但是我尝试在viewDidLoad()中添加一些代码来第一次设置它,而这并不是似乎有所帮助。

这是我的代码:

override func viewDidLoad() {
    super.viewDidLoad()

    itemSelected = "Moss"
    NSUserDefaults.standardUserDefaults().setObject(itemSelected, forKey: "colourChosen")
}

override func viewWillAppear(animated: Bool) {
    itemSelected = NSUserDefaults.standardUserDefaults().stringForKey("colourChosen")!
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    itemSelected = colours[row]
    NSUserDefaults.standardUserDefaults().setObject(itemSelected, forKey: "colourChosen")
}

该应用程序在viewWillAppear()

中崩溃

有人有什么想法吗?

1 个答案:

答案 0 :(得分:2)

设置对象后,您没有调用synchronize()

let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(itemSelected, forKey: "colourChosen")
userDefaults.synchronize()
             ^^^^

没有它,不会立即保存任何更改。这可能是原因。

每次更改用户默认值时都必须调用

synchronize,并且您希望立即保留更改(系统会在特定时间间隔自动调用它)。

但是,在viewWillAppear实现中,我注意到您正在使用强制解包,除非您100%确定可选实际包含非零值,否则应始终避免使用强制解包。我会用可选的绑定来保护那个展开:

if let colour = NSUserDefaults.standardUserDefaults().stringForKey("colourChosen") {
    itemSelected = color
}

<强>更新

我注意到itemSelected是您存储在用户默认值中的临时容器。您可以考虑在计算属性中移动用户默认代码,以防止每次读取或修改该属性时出现代码重复 - 例如:

private var _itemSelected : String?

var itemSelected : String? {
    get {
        if _itemSelected == nil {
            _itemSelected = NSUserDefaults.standardUserDefaults().stringForKey("colourChosen")
        }
        return _itemSelected
    }
    set {
        let userDefaults = NSUserDefaults.standardUserDefaults()
        userDefaults.setObject(newValue, forKey: "colourChosen")
        userDefaults.synchronize()
    }
}

其中_itemSelected只是一个缓存值 - 或类似的实现,但没有缓存值:

var itemSelected : String? {
    get {
        return NSUserDefaults.standardUserDefaults().stringForKey("colourChosen")
    }
    set {
        let userDefaults = NSUserDefaults.standardUserDefaults()
        userDefaults.setObject(newValue, forKey: "colourChosen")
        userDefaults.synchronize()
    }
}

请注意,在这两种情况下,属性类型都是可选字符串