подготовить переход, неожиданно найденный ноль при развертывании необязательного значения

Да, другой обнаружил nil при распаковке ошибки необязательного значения. Я прочитал тонны других сообщений о переполнении стека с похожими ошибками, такими как этот и многие другие. Я до сих пор не до конца понимаю, как правильно работать с разворачиванием переменной.

У меня есть класс, похожий на следующий:

@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!)».


person D. Cohen    schedule 17.10.2016    source источник


Ответы (2)


Ответ Сахила находится на правильном пути, но не касается того, что valueInput также является необязательным. Используйте этот код:

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

В дополнение к правильному развертыванию необязательного valueInput я хотел добавить, что есть вероятность, что если valueInput является IBOutlet, он определяется как:

@IBOutlet weak var valueInput: UITextField!

Это называется неявно развернутым необязательным. Раздражает то, что, поскольку это также IBOutlet, если он когда-нибудь отключится от UITextField в Interface Builder, переменная станет нулевой, и доступ к ней из любого места в коде вызовет сбой.

Измените его на это:

@IBOutlet weak var valueInput: UITextField?

Я также написал об этом в своем блоге: http://cleanswifter.com/implicitly-unwrapped-iboutlets/

Примечание: вы не показали определение valueInput, поэтому я предположил, что это UITextField

person Andy Obusek    schedule 17.10.2016
comment
Да, это было частью проблемы! Я отредактирую код в своем вопросе - person D. Cohen; 17.10.2016
comment
Хорошо, отлично, так это решило проблему? - person Andy Obusek; 17.10.2016
comment
ага! Большое спасибо! - person D. Cohen; 18.10.2016

Вы можете безопасно развернуть значение, используя конструкцию if let

var value : Int? = nil 

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

а также вы можете сделать это с помощью нулевого оператора объединения ?? одной строкой

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

ОБНОВЛЕНИЕ

Сначала проверьте, не отключены ли текстовые поля от Interface Builder, если не подключены, подключите их. и если вы станете необязательными для текстовых полей, вам также необходимо безопасно развернуть текстовые поля (вы забыли добавить его из построителя интерфейса, и он не сработает, если вы сделаете их необязательными).

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)

}
person Sahil    schedule 17.10.2016
comment
большое вам спасибо за вашу помощь! Я все еще получаю ошибку, хотя - person D. Cohen; 17.10.2016
comment
для if let ошибка возникает в строке «if let val = valueInput.text». Это также происходит в строке оператора объединения nil. - person D. Cohen; 17.10.2016
comment
Смотрите мой ответ, valueInput является необязательным, то есть нулевым, НЕ valueInput.text - person Andy Obusek; 17.10.2016
comment
хорошо. похоже, что ваши текстовые поля отключены от Interface Builder (подключите их), и если ваше nameTextField и valueInput являются необязательными. вы также должны сначала выполнить необязательную привязку. я обновлю ответ - person Sahil; 17.10.2016