防止具有零可选值的开关按钮

时间:2016-09-19 19:28:40

标签: ios swift boolean optional-binding

如果在设置中设置了开关,我会运行一段代码,如下所示:

UserDefaults.standard.bool(forKey: "signatureSwitchState")

        let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as! Bool

        if buttonState == true {

            sign()

        }

我的问题是,如果交换机从未被激活,程序将失败,因为编译器声明“致命错误:在展开可选值时意外发现nil”

我的问题是,当使用bool(例如上述声明中的开关)时,如何最好地防止零值。

我已经尝试过let语句和保护语句但是编译器抱怨这些不能和bool一起使用。

5 个答案:

答案 0 :(得分:1)

您应该使用:

let buttonState = UserDefaults.standard.bool(forKey: "signatureSwitchState")

如果未明确设置该值,则返回false。

答案 1 :(得分:1)

如果您尝试从UserDefaults获取bool,可以使用

let buttonState = UserDefaults.standard.bool(forKey: "signatureSwitchState")

此函数返回一个Bool,因此您知道该值只能为true或false,如果它没有找到该键的值,则它将返回false。您正在使用的功能

UserDefaults.standard.object(forKey: "signatureSwitchState")

返回一个AnyObject?所以它可以是零。

答案 2 :(得分:1)

鲜为人知,但Apple强烈推荐:

注册默认值,直到用户第一次更改值时才会考虑这些值。

applicationDidFinishLaunching中 - 至少在第一次访问该值之前 - 注册键/值对。

let userDefaults = UserDefaults.standard
let defaultValues : [String : Any] = ["signatureSwitchState" : false]
userDefaults.register(defaults: defaultValues)

现在值永远不会nil(我知道Bool示例相当弱)

let buttonState = UserDefaults.standard.bool(forKey: "signatureSwitchState")

与#34;原语相比,对象更有利于这种方式。无论如何都不会nil的类型。

答案 3 :(得分:0)

有几种方法可以做到这一点。既然这是一个bool,那么使用nil-coalescing ??可能最简单:

let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as? Bool ?? false

或者,您可以使用guard来执行此操作,这可能更强大:

guard let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as? Bool else { return }
if buttonState == true {
    sign()
}

请注意,在这两种情况下,您都必须将强制展开(!)更改为可选的展开(?)。

答案 4 :(得分:0)

我有一个可能在将来有用的提示,虽然它不如picciano answer那么好,这绝对是正确的方法。

UserDefaults.standard.object(forKey: "signatureSwitchState")会返回AnyObject

如果您尝试强制转换为Boolas! Bool),如果返回的值不是Bool,或者nil,则会崩溃。相反,如果您有条件地投射(as? Bool),您将收到Bool?。这会将值转换为Bool(如果存在),否则它会给你nil(不会崩溃。

从那里,您可以使用nil合并运算符(Bool?)将此Bool转换为??。如果有值,它会返回Bool值,否则它将返回您给出的默认值。在这种情况下,false

另外,由于buttonState已经是Bool,因此没有理由将其与true语句中的if进行比较。直接使用它:

let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as? Bool ?? false
if buttonState {
    sign()
}