0

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

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

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

        if buttonState == true {

            sign()

        }

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

那么我的问题是,在使用上述语句中的 switch 之类的 bool 时,如何最好地防止出现 nil 值。

我尝试过 if let 语句和 guard 语句,但编译器抱怨这些不能与 bool 一起使用。

4

5 回答 5

1

你应该使用:

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

如果该值没有显式设置,它将返回 false。

于 2016-09-19T19:36:56.643 回答
1

如果您尝试从 UserDefaults 获取布尔值,您可以使用

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

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

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

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

于 2016-09-19T19:37:14.210 回答
1

鲜为人知,但苹果强烈推荐:

注册默认值,直到用户第一次更改该值。

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

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

现在价值永远不会nil(我知道这个Bool例子很弱)

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

对象比永远不会的“原始”类型更能利用这种方式nil

于 2016-09-19T19:58:17.290 回答
0

我有一个提示可能会在将来有用,尽管它不如picciano答案那么好,这绝对是正确的方法。

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

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

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

另外,因为buttonState已经是 a Bool,所以没有理由true在您的if陈述中将其与它进行比较。直接使用即可:

let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as? Bool ?? false
if buttonState {
    sign()
}
于 2016-09-19T19:36:28.730 回答
0

有几种方法可以做到这一点。由于这是一个布尔值,因此使用 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()
}

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

于 2016-09-19T19:36:03.047 回答