准备 segue 在展开可选值时意外发现 nil

prepare segue unexpectedly found nil while unwrapping an Optional value

是的,另一个 在解包可选值错误时发现 nil。我已经阅读了大量其他类似错误的堆栈溢出帖子,例如 一个和许多其他错误。我仍然不完全理解如何正确处理展开变量。

我有一个 class 类似于以下内容:

@IBOutlet weak var nameTextField: UITextField?
@IBOutlet weak var valueInput: UITextField?

var checkbox : CheckBox?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let name = nameTextField.text ?? ""
    let state = buttonState.getIsChecked()
    let value : Int? = Int(valueInput.text!)
    let isMoveable = true

    checkbox = CheckBox(name: name, value: value, state: state, isMoveable: isMoveable)
}

我在 "let value : Int? = Int(valueInput.text!) 行收到错误。

您可以使用 if let 构造

安全地展开值
var value : Int? = nil 

if let val = valueInput.text {
  value = Int(val) // it would either nil or optional value
}

你也可以通过 nil coalescing operator ?? 在一行中完成

let value : Int? = Int(valueInput.text ?? "")

更新

首先检查文本字段是否与界面生成器断开连接,如果未连接,则连接它们。如果你成为你的文本字段可选,你还必须安全地打开文本字段(你忘记从界面构建器添加它,如果你将它们设为可选,它不会崩溃)。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

var name: String? = nil
var value : Int? = nil
let state = buttonState.getIsChecked()
let isMoveable = true


if let nameTextField = self.nameTextField where nameTextField.text != nil {
  name = nameTextField.text!
}

if let valueTextField = self.valueInput where valueTextField.text != nil {
  value = Int(valueTextField.text!)
}

 checkbox = CheckBox(name: name, value: value, state: state, isMoveable: isMoveable)

}

Sahil 的回答是正确的,但没有说明 valueInput 也是可选的。使用此代码:

if let valueInput = valueInput,
    let val = valueInput.text {
    value = Int(val)
}

此外,关于正确解包可选的 valueInput 我想补充一点,如果 valueInput 是一个 IBOutlet,则它被定义为:

@IBOutlet weak var valueInput: UITextField!

这称为隐式解包可选。烦人的是,因为它也是一个 IBOutlet,如果它在 Interface Builder 中与 UITextField 断开连接,变量将变为 nil,从代码中的任何地方访问它都会导致崩溃.

改成这样:

@IBOutlet weak var valueInput: UITextField?

我也在我的博客上写过:http://cleanswifter.com/implicitly-unwrapped-iboutlets/

注意:您没有显示 valueInput 的定义,所以我假设它是 UITextField