我试图在可选值的情况下处理编译器。任务非常简单,我的func获取用户默认值以在tableview中显示它们。如果用户首次启动应用,则会设置默认值。设置默认值工作正常(使用打印日志检查),但提取原因:
致命错误:在解包可选值时意外发现nil
我已经和选项一起工作了很长时间,但是,也许我仍然对它们感到困惑,因为我发现一切似乎都是正确的甚至编译器都说,一切没关系。
func getFiltersSetts() -> [String] {
let userDefs = NSUserDefaults.standardUserDefaults()
var defsArray = [String]()
if (userDefs.objectForKey("gender") != nil) {
defsArray.append((userDefs.objectForKey("gender")?.stringValue)!)
defsArray.append((userDefs.objectForKey("age")?.stringValue)!)
defsArray.append((userDefs.objectForKey("online")?.stringValue)!)
}
else {
userDefs.setObject("Male", forKey: "gender")
userDefs.setObject("21-30", forKey: "age")
userDefs.setObject("Online", forKey: "online")
}
return defsArray
}
答案 0 :(得分:3)
你强行打开你的选项,你应该在将它们附加到数组之前将它们作为字符串。
设置默认值的更简洁方法是合并您的选项的展开,请尝试以下方法:
func getFiltersSetts() -> [String] {
let userDefs = NSUserDefaults.standardUserDefaults()
var defsArray = [String]()
defsArray.append(userDefs.stringForKey("gender") ?? "Male")
defsArray.append(userDefs.stringForKey("age") ?? "21-30")
defsArray.append(userDefs.stringForKey("online") ?? "Online")
return defsArray
}
上面的代码使用coalesce(??)运算符。如果您的可选项,例如userDefs.stringfForKey(“gender”)返回nil,则coalesce运算符将使用默认值“Male”。
然后稍后您可以保存用户默认值(或创建它们),如果之前尚未设置的话。
此外,值得注意的是,您应该使用如果让表示法打开您的选项。而不是比较它的!= nil,因为这会阻止你强行将它们展开到代码块中。
我希望这有帮助!
答案 1 :(得分:2)
Apple强烈建议您通过registerDefaults
的{{1}}设置默认值。
尽快(至少在第一次使用之前)设置默认值,例如NSUserDefaults
:
applicationDidFinishLaunching
在设置新值之前,会考虑默认值。
好处是你有从不来处理选项和类型转换。
let userDefs = NSUserDefaults.standardUserDefaults()
let defaultValues = ["gender" : "Male", "age" : "21-30", "online" : "Online"]
userDefs.registerDefaults(defaultValues)
强制展开是100%安全的,因为没有一个密钥可以func getFiltersSetts() -> [String] {
let userDefs = NSUserDefaults.standardUserDefaults()
return [userDefs.stringForKey("gender")!,
userDefs.stringForKey("age")!,
userDefs.stringForKey("online")!]
}
。
请阅读Registering Your App’s Default Preferences
中的Preferences and Settings Programming Guide答案 2 :(得分:0)
您可以创建默认密钥“firstBootCompleted”。然后使用:
let defaults = NSUserDefaults.standardUserDefaults()
if (defaults.boolForKey("firstBootCompleted") == false) {
defaults.setObject(true, forKey: "firstBootCompleted")
// Initialize everything for your first boot below
} else {
// Initialize everything for not your first boot below
}
这有效的原因是,当密钥对象为boolForKey
时,false
会返回nil
答案 3 :(得分:0)
您将所有值存储为String
,然后在提取时存储
您在String
userDefs.objectForKey("gender")?.stringValue
String
无法再次转换为String
。
尝试以
进行访问userDefs.stringForKey("gender")