подготви сегю неочаквано намерена нула, докато разопакова незадължителна стойност

Да, друго намери нула при разопаковане на грешка с незадължителна стойност. Прочетох тонове други публикации за препълване на стека с подобни грешки като този и много други. Все още не разбирам напълно как да се справя правилно с разгръщането на променлива.

Имам клас, който е подобен на следния:

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


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


Отговори (2)


Отговорът на Sahil е на път, но не се отнася до това, че 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'. Среща се и на линията на оператора за нулево обединяване - 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