Поток 1: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, субкод = 0x0), когда символы превышаются - PullRequest
0 голосов
/ 13 января 2019

Я знаю, что есть ответы относительно этого исключения, но у меня ничего не работает.

Мой код работал нормально, когда мне приходилось преобразовывать текст текстового поля в Int, но теперь я заметил, что при вводе более 10 символов происходит сбой.

Я установил предел символов в этих текстовых полях равным 11, но он падает на последнем номере с ошибкой: Поток 1: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, субкод = 0x0).

Вот код

@IBAction func Qty_EndEdit(_ sender: Any) {
    print("For Total Cost")
    if QtyText.text != ""{
        if UnitPriceText.text != "" {
            TotalCostText.text = String((QtyText.text?.numberValue)! * (UnitPriceText.text?.numberValue)!)
        }
    }
}

@IBAction func UnitPrice_EndEdit(_ sender: Any) {
    print("For Total Cost")
    if QtyText.text != ""{
        if UnitPriceText.text != "" {
         TotalCostText.text = String((QtyText.text?.numberValue)! * (UnitPriceText.text?.numberValue)!)  
 // CRASHING ON THE ABOVE LINE   
        }
    }
}

extension String {
    var numberValue:Int? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.number(from: self) as! Int
    }
}

1 Ответ

0 голосов
/ 14 января 2019

Ваш сбой связан с тем, что умножение Int не может обработать такие числа, используйте Double.

Оба ваших действия делают одно и то же, попробуйте поместить код, который будет повторно использоваться внутри func.

Вам также нужно посмотреть на дополнительные функции и как их использовать. Вот пример.

func updateTotalCost() {
    if let quantity = Double(QtyText.text ?? ""),
        let unitPrice = Double(UnitPriceText.text ?? "") {
        TotalCostText.text = String(quantity * unitPrice)
    } else {
        // ???
        TotalCostText.text = ""
    }
}

@IBAction func Qty_EndEdit(_ sender: Any) {
    updateTotalCost()
}

@IBAction func UnitPrice_EndEdit(_ sender: Any) {
    updateTotalCost()
}

Я рассечу некоторые из них:

QtyText.text ?? "" -> Если QtyText.text равен nil, замените его пустой строкой, в противном случае используйте значение в QtyText.text

Double(QtyText.text ?? "") -> Построить Double from a String , which is guaranteed non-nil (since we forced it to be an empty String`, даже если QtyText.text был равен nil)

Этот конструктор Double() может сам по себе возвращать nil, если строка, переданная конструктору, не имеет допустимого значения Double (например, String "abcd" не может вычисляться до Double). Поэтому мы заключаем это в оператор if let, чтобы защитить себя от конструктора Double(), который не может создать Double из нашего String:

    if let quantity = Int(QtyText.text ?? "")

Это говорит компилятору:

Оцените это как истинное, только если то, что я помещаю в переменную количества, не равно нулю.

Наконец, мы объединяем два оператора if запятыми:

    if let quantity = Int(QtyText.text ?? ""),
        let unitPrice = Int(UnitPriceText.text ?? "") {

Внутри этой части оператора if мы гарантируем, что количество и unitPrice действительны Doubles, и что мы можем выполнить вычисление.

Я не уверен, что вам будет, пожалуйста, результат String(myDoubleNumber), но тогда вам следует изучить форматирование чисел, чтобы получить то, что вы хотите.

...