Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios stringForKey崩溃应用程序_Ios_Swift_Nsuserdefaults - Fatal编程技术网

Ios stringForKey崩溃应用程序

Ios stringForKey崩溃应用程序,ios,swift,nsuserdefaults,Ios,Swift,Nsuserdefaults,我试图在NSUserDefaults中存储一个字符串,但是当我去检索它时,我的应用程序崩溃了 我假设这只是第一次发生,因为在NSUserDefaults中从未为该键设置过值,但是我尝试在viewDidLoad()中添加一些代码来第一次设置它,这似乎没有帮助 这是我的密码: override func viewDidLoad() { super.viewDidLoad() itemSelected = "Moss" NSUserDefaults.standardUserD

我试图在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")
}
应用程序在
viewwillappease()中崩溃


有人有什么想法吗?

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

let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(itemSelected, forKey: "colourChosen")
userDefaults.synchronize()
             ^^^^
否则,不会立即保存任何更改。这可能就是原因

synchronize
必须在每次更改用户默认值时调用,并且您希望立即保留更改(系统会在特定时间间隔自动调用它)

但是,在您的
视图将出现
实现中,我注意到您使用的是强制展开,除非您100%确定可选值实际上包含非nil值,否则应始终避免使用强制展开。我会用一个可选的绑定来保护展开:

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()
    }
}
其中,
\u itemSelected
只是一个缓存值-或类似的实现,但没有缓存值:

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

请注意,在这两种情况下,属性类型都是可选字符串,不幸的是,这不是问题所在。您确定必须使用
同步()
?我已经多次使用NSUserDefaults,以前从未使用过它。它会定期自动调用,但如果您希望更改立即可用,最好使用它。这可能是你的情况,尽管它不能解决问题。你能在你的问题中发表你有什么例外吗?我没有注意到
将出现在
视图中的行尾
。这会导致强制展开,如果密钥不存在,很可能是异常的原因。我建议用一个可选的绑定来包装它,非常感谢!我正要回答说所有的解决方案都不起作用,但我遇到了一个不相关的问题。