我有一个属性观测器代码,必须修改iboutlet属性:
@IBOutlet weak var canYouGuessLbl: UILabel!
var isNewUser: Bool = false {
didSet {
if isNewUser {
canYouGuessLbl!.layer.zPosition = 5
canYouGuessLbl!.hidden = false
} else {
canYouGuessLbl!.hidden = true // Error at this line
}
}
}
这在运行时崩溃,因为canYouGuessLbl!似乎为零:
fatal error: unexpectedly found nil while unwrapping an Optional value
我不确定原因以及如何解决这个问题。
如果您的问题出现在Antonio答案的第一个场景中,那么您可以通过将isNewUser变量声明为可选变量来解决它,并在canYouGuessLbl完全初始化后在viewDidLoad方法上为其赋值
var isNewUser: Bool! {
didSet(newValue) {
if isNewUser != nil && isNewUser! {
canYouGuessLbl!.layer.zPosition = 5
canYouGuessLbl!.hidden = false
} else if isNewUser != nil && !isNewUser! {
canYouGuessLbl!.hidden = true
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
isNewUser = false
}
当为isNewUser
:分配新值时,canYouGuessLbl
可能为零的原因有几个
-
在
canYouGuessLbl
被初始化之前(在viewDidLoad
之前,例如在初始化器中),isNewUser
被分配一个新值 -
尚未为
canYouGuessLbl
定义出口(即接口生成器中的标签控件尚未连接到属性) -
IB中的视图控制器未连接到实现类(身份检查器中的自定义类)
更新-在第一种情况下,可以通过显式检查not nil:进行修复
var isNewUser: Bool = false {
didSet {
if canYouGuessLbl != nil {
if isNewUser {
canYouGuessLbl.layer.zPosition = 5
canYouGuessLbl.hidden = false
} else {
canYouGuessLbl.hidden = true // Error at this line
}
}
}
}
但是请注意,这样做不会更新标签(因为它还不存在)。它只是防止出现异常。
附加说明:初始化属性时不会调用didSet
(以及更常见的属性观测器)。
谢谢你们的回答。它启发了我这个解决方案:
我不得不把要执行的操作放在一个单独的功能中:
func ifNewUser() {
if isNewUser! {
canYouGuessLbl?.layer.zPosition = 5
canYouGuessLbl?.hidden = false
} else if !isNewUser! {
canYouGuessLbl?.layer.zPosition = 5
canYouGuessLbl?.hideAndDisable()
}
}
主要的问题是初始化,所以我首先在viewDidLoad:中检查
ifNewUser()
因为bool值很早就通过segue接收到它的值,所以在初始化包括IBoutlet在内的所有变量后,最好先在viewDidLoad中检查它。
然后,当用户不再被声明为新用户时,我保留观察者,但调用函数:
var isNewUser: Bool? {
didSet {
ifNewUser()
}
}
完成任务。