Swift属性观察者和nil



我有一个属性观测器代码,必须修改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()
        }
    } 

完成任务。

最新更新