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

Ios 防止具有零可选值的开关按钮,ios,swift,boolean,optional-binding,Ios,Swift,Boolean,Optional Binding,我有一段代码,如果在如下设置中设置了开关,则该代码将运行: UserDefaults.standard.bool(forKey: "signatureSwitchState") let buttonState = UserDefaults.standard.object(forKey: "signatureSwitchState") as! Bool if buttonState == true { sign() }

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

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

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

        if buttonState == true {

            sign()

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

我的问题是,在使用bool(如上面语句中的开关)时,如何最好地防止出现nil值


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

有几种方法可以做到这一点。因为这是一个bool,所以可能最简单的方法就是使用nil合并
??

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()
}

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

有几种方法可以做到这一点。因为这是一个bool,所以可能最简单的方法就是使用nil合并
??

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()
}

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

我有一个技巧,将来可能会有用,尽管它不如的好,这肯定是正确的方法

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

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

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

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

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

我有一个建议,将来可能会有用,尽管它不如的好,这绝对是正确的方法

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

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

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

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

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

let buttonState = UserDefaults.standard.bool(forKey: "signatureSwitchState")
如果未明确设置该值,它将返回false。

您应该使用:

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

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

如果您试图从可以使用的UserDefaults获取bool

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

此函数返回Bool,这样您就知道该值只能是true或false,如果它找不到键的值,那么它将返回false

UserDefaults.standard.object(forKey:“signatureSwitchState”)


返回一个AnyObject?因此它可以是nil。

如果您试图从您可以使用的UserDefaults获取bool

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

此函数返回Bool,这样您就知道该值只能是true或false,如果它找不到键的值,那么它将返回false

UserDefaults.standard.object(forKey:“signatureSwitchState”)


返回AnyObject?因此可以为零。

鲜为人知,但苹果公司强烈建议:

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

ApplicationIDFinishLaunching
中–至少在第一次访问值之前–注册密钥/值对

现在,值决不是
nil
(我知道
Bool
示例非常弱)


这些对象比“原语”类型更能利用这种方式,因为“原语”类型从来都不是
nil

鲜为人知,但苹果公司极力推荐:

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

ApplicationIDFinishLaunching
中–至少在第一次访问值之前–注册密钥/值对

现在,值决不是
nil
(我知道
Bool
示例非常弱)

与“基本”类型相比,对象利用这种方式的优势要大得多,而“基本”类型无论如何都不是
nil

可能重复的