Swift плохая инструкция, список покупок

У меня проблема, Xcode выдает мне эту ошибку "EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP,subcode==0*0)", в то время как я пытаюсь заставить свои кнопки удалять индексы в моем массиве "shoppingList". Пожалуйста, помогите мне и скажите мне, что я сделал не так, чтобы я мог улучшить позже.

//
//  ViewController.swift
//  ShoppingList
//
//  Created by Petr Chrastek on 29/03/16.
//  Copyright © 2016 ACS. All rights reserved.
//
class ViewController: UIViewController {
    @IBOutlet weak var labelText: UILabel!
    @IBOutlet weak var label0: UILabel!
    @IBOutlet weak var label1: UILabel!
    @IBOutlet weak var label2: UILabel!
    @IBOutlet weak var label3: UILabel!
    var shoppingList = ["eggs", "milk", "cake", "sugar"]

    @IBAction func remove0(sender: UIButton) {
        shoppingList.removeAtIndex(0)
    }

    @IBAction func remove1(sender: UIButton) {
        shoppingList.removeAtIndex(1)
    }

    @IBAction func remove2(sender: UIButton) {
        shoppingList.removeAtIndex(2)
    }

    @IBAction func remove3(sender: UIButton) {
        shoppingList.removeAtIndex(3)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let str: String? = shoppingList[0]
        let str1: String? = shoppingList[1]
        let str2: String? = shoppingList[2]
        let str3: String? = shoppingList[3]
        let count = shoppingList.count
        labelText.text? = "you are missing \(count) items"
        if str != nil {
            label0.text? = "\(str)"
        } else {
            label0.text? = "empty"
        }
        if str1 != nil {
            label1.text? = "\(str1)"
        } else {
            label1.text? = "empty"
        }
        if str2 != nil {
            label2.text? = "\(str2)"
        } else {
            label2.text? = "empty"
        }
        if str3 != nil {
            label3.text? = "\(str3)"
        } else {
            label3.text? = "empty"
        }
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

1 ответ

После того, как вы удалите первый элемент из вашего списка, shoppingList будет иметь только 3 элемента, так что доступ shoppingList[3] произойдет сбой (помните, что с 3 элементами только 0..<2 действительны.

Самый простой способ решить эту проблему - использовать следующий шаблон, чтобы проверить счетчик, чтобы убедиться, что индексы действительны перед их использованием.

if shoppingList.count > 0 {
    label0.text = shoppingList[0]
} else {
    label0.text = "empty"
}

if shoppingList.count > 1 {
    label1.text = shopingList[1]
} else {
    label1.text = "empty"
}

Я также внес некоторые дополнительные изменения, такие как использование бессмысленной интерполяции строк для String в то же самое String, поскольку [String][n] всегда будет возвращать String (никогда String?) нет необходимости иметь дело с Optionals

У вас будут похожие проблемы (на самом деле, вероятно, с чем вы сейчас столкнулись), когда вы попытаетесь:

shoppingList.removeAtIndex(3)

во второй раз, так как 3 больше не является допустимым индексом, вместо этого используйте:

if shoppingList.count > 3 {
    shoppingList.removeAtIndex(3)
}
Другие вопросы по тегам