简体   繁体   English

斯威夫特物业观察员和零

[英]Swift property observer and nil

I have a property observer code that must modify an iboutlet property: 我有一个必须修改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
        }

    }
}

This crashes at runtime because canYouGuessLbl! 这在运行时崩溃,因为canYouGuessLbl! seems to be nil: 似乎是零:

fatal error: unexpectedly found nil while unwrapping an Optional value

I'm not sure about the reason and how to resolve this. 我不确定原因以及如何解决这个问题。

If your problem occur in scenario number one of Antonio's answer then you can solve it by declaring your isNewUser variable as optional and assign value to it on viewDidLoad method after canYouGuessLbl is fully initialized 如果您的问题出现在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
}

There are a few reasons why canYouGuessLbl could be nil when assigning a new value to isNewUser : 有几个原因canYouGuessLbl可以分配一个新的值时,零isNewUser

  • isNewUser is assigned a new value before canYouGuessLbl has been initialized (prior to viewDidLoad , such as in an initializer) isNewUsercanYouGuessLbl初始化之前被赋予一个新值(在viewDidLoad之前,例如在初始化程序中)

  • an outlet has not been defined for canYouGuessLbl (ie the label control in interface builder has not been connected to the property) 尚未为canYouGuessLbl定义canYouGuessLbl (即接口生成器中的标签控件尚未连接到属性)

  • the view controller in IB is not connected to the implementation class (custom class in identity inspector) IB中的视图控制器未连接到实现类(身份检查器中的自定义类)

Update - In the first case, you can fix by explicitly checking for not nil: 更新 - 在第一种情况下,您可以通过显式检查不是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
            }
        }
    }
}

Note however that doing that the label won't be updated (because it doesn't exist yet). 但是请注意,标签不会更新(因为它还不存在)。 It just prevents the exception. 它只是防止异常。

Additional note: didSet (and more generally property observers) is not invoked when the property is initialized. 附加说明:初始化属性时,不会调用didSet (更didSet是属性观察者)。

Thanks for your answers guys. 谢谢你的答案。 It inspired me for this solution: 它启发了我这个解决方案:

I had to put the action to perform in a separate function: 我必须将动作放在一个单独的函数中执行:

    func ifNewUser() {
    if isNewUser! {
        canYouGuessLbl?.layer.zPosition = 5
        canYouGuessLbl?.hidden = false
    } else if !isNewUser! {
        canYouGuessLbl?.layer.zPosition = 5
        canYouGuessLbl?.hideAndDisable()
    }
}

The main problem was with initialization, so first I check this in viewDidLoad: 主要问题是初始化,所以首先我在viewDidLoad中检查它:

ifNewUser()

Because the bool value receives its value very early by a segue, It's appropriate to check it first in viewDidLoad after all the variables including the IBoutlets are initialized. 因为bool值很早就会通过segue接收到它的值,所以在初始化包括IBoutlet在内的所有变量之后,首先在viewDidLoad中检查它是合适的。

Then for when the user is not declared a new user anymore, I keep the observer, but with call to function: 然后,当用户不再被宣布为新用户时,我保留了观察者,但是调用了函数:

    var isNewUser: Bool? {
    didSet {
        ifNewUser()
        }
    } 

Does the job. 这份工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM