简体   繁体   English

“线程 1:致命错误:索引超出范围”来自以零/空长度初始化的数组,但在请求时绝对不为空

[英]"Thread 1: Fatal error: Index out of range" from an array initialized with a length of zero/empty but it's definitely not empty when requested

So I currently have a tableView in a ViewController called GearComponentViewController that has custom tableViewCells that have a UIStepper in them to control a quantity label and conforms to the custom protocol Stepper .所以我目前在一个名为GearComponentViewController的 ViewController 中有一个 tableView ,它有一个自定义 tableViewCells ,其中有一个 UIStepper 来控制数量 label 并符合自定义协议Stepper

protocol Stepper {
func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int)
}

And here's the code for the GearComponentTableViewCell :这是GearComponentTableViewCell的代码:

class GearComponentTableViewCell: UITableViewCell {

var mainVC = GearComponentViewController()
var tableViewCellPosition: Int! = nil

// Image
@IBOutlet weak var itemImage: UIImageView!

// Name
@IBOutlet weak var itemName: UILabel!

// Weight
@IBOutlet weak var itemWeight1: UILabel!
@IBOutlet weak var itemWeight2: UILabel!

// Quanity
@IBOutlet weak var itemQuanity: UILabel!
@IBAction func stepperPressed (_ sender: UIStepper!){
    if (sender.value == 1) {
        print("up and item: \(itemName.text!)");
        sender.value = 0
        mainVC.stepperWasPressed(didIncrease: true, namePassed: itemName.text!, userindexPath: tableViewCellPosition)
    } else if (sender.value == -1) {
        print("down and item: \(itemName.text!)");
        sender.value = 0
        mainVC.stepperWasPressed(didIncrease: false, namePassed: itemName.text!, userindexPath: tableViewCellPosition)
    }
}

// Notes
@IBOutlet weak var itemNotes: UILabel!

} }

It detects if the user clicked on the plus button or the minus button on the stepper and calls the function from the protocol stepperWasPressed()它检测用户是否单击了步进器上的加号按钮或减号按钮,并从协议stepperWasPressed()调用 function

Finally here's the code for the mainVC referenced:最后是引用的mainVC的代码:

extension GearComponentViewController: Stepper {
    
    func refreshTableViewCell() {
        print("arrayPosition: \(arrayPosition)")
//        gearTableView.reloadData()
    }
    
    
    
    func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int) {
        
        if didIncrease {
            arrayPosition = userindexPath
            print("arrayPosition: \(arrayPosition)")
//            itemArray[userindexPath].quanity += 1
            print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
            print("increase selected")
            refreshTableViewCell()
        }else {
            arrayPosition = userindexPath
            print("arrayPosition: \(arrayPosition)")
//            itemArray[userindexPath].quanity -= 1
            print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
            print("decrease selected")
            refreshTableViewCell()
        }
    }
}

When I try to do either itemArray[userindexPath].quanity += 1 or itemArray[userindexPath].quanity -= 1 I'm getting the error listed in the title, but to be even able to call that part of the function the count of my itemArray has to be greater than zero/empty because I'm being presented a cell with a stepper in it.当我尝试执行itemArray[userindexPath].quanity += 1itemArray[userindexPath].quanity -= 1时,我得到了标题中列出的错误,但甚至能够调用 function 的那部分计数我的 itemArray 必须大于零/空,因为我看到的是一个带有步进器的单元格。

Full GearComponentViewController:完整的 GearComponentViewController:

import UIKit

class GearComponentViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var arrayPosition: Int = 0
    
    // Data Sources
    var itemArray: [GearItem] = []
    var totalWeight1: Int = 0
    var totalWeight2: Int = 0
    var totalItems: Int = 0
    
    // Weight Label Outlets
    @IBOutlet weak var weight1LabelOutlet: UILabel!
    @IBOutlet weak var weight2LabelOutlet: UILabel!
    
    // Item Count Label Outlet
    
    @IBOutlet weak var totalCountLabelOutlet: UILabel!
    
    // TableView Outlet
    @IBOutlet weak var gearTableView: UITableView!
    
    // Bar Button Item
    @IBAction func addItemPressed(_ sender: Any) {
        presentAlert()
    }
    
    // View Did Load
    override func viewDidLoad() {
        super.viewDidLoad()
        gearTableView.dataSource = self
        gearTableView.delegate = self
        print("Gear Component View Controller successfully loaded.")
        
        updateUI()
        // Do any additional setup after loading the view.
    }
    
    //MARK: - UI Updater
    func updateUI() {
        addTotalWeight()
        addAllItems()
    }
    
    // Adding Total Weight
    func addTotalWeight() {
        var addedWeight1: Int = 0
        var addedWeight2: Int = 0
        
        for item in itemArray {
            addedWeight1 += item.weight1 * item.quantity
            addedWeight2 += item.weight2 * item.quantity
        }
        
        totalWeight1 = addedWeight1
        totalWeight2 = addedWeight2
        
        weight1LabelOutlet.text = String("\(totalWeight1)")
        weight2LabelOutlet.text = String("\(totalWeight2)")
    }
    
    // Item Count
    func addAllItems() {
        var addedValue: Int = 0
        
        for item in itemArray {
            addedValue += item.quantity
        }
        totalItems = addedValue
        
        totalCountLabelOutlet.text = String("\(totalItems)")
        print("Total items: \(totalItems)")
    }
    
   
    
    
    //MARK: - Alert
    func presentAlert() {
        let alertController = UIAlertController(title: "Add Item", message: "Enter item info here", preferredStyle: .alert)
        
        // AlertController Textfields
        alertController.addTextField { (textField) in
            textField.placeholder = "Name"
        }
        alertController.addTextField { (textField) in
            textField.placeholder = "Weight 1"
            textField.keyboardType = .decimalPad
        }
        alertController.addTextField { (textField) in
            textField.placeholder = "Weight 2"
            textField.keyboardType = .decimalPad
        }
        alertController.addTextField { (textField) in
            textField.placeholder = "Quanity"
            textField.keyboardType = .decimalPad
        }
        alertController.addTextField { (textField) in
            textField.placeholder = "Notes"
        }
        
        // AlertController Actions
        let continueAction = UIAlertAction(title: "Add", style: .default) { [self, weak alertController] _ in
            guard let textFields = alertController?.textFields else { return }
            
            if let userItemName = textFields[0].text,
               let userItemWeight1 = textFields[1].text,
               let userItemWeight2 = textFields[2].text,
               let userItemQuanity = textFields[3].text,
               let userItemNotes = textFields[4].text {
                
                print("Name: \(userItemName)")
                print("Item Weight 1: \(userItemWeight1)")
                print("Item Weight 2: \(userItemWeight2)")
                print("Item Quantity: \(userItemQuanity)")
                print("Item Notes: \(userItemNotes)")
                
                let userSubmittedItem = GearItem(itemName: userItemName, itemImage: UIImage(systemName: "photo.on.rectangle.angled")!, itemWeight1: Int(userItemWeight1) ?? 0, itemWeight2: Int(userItemWeight2) ?? 0, itemQuantity: Int(userItemQuanity) ?? 1, itemNotes: userItemNotes ?? "", creationPosition: itemArray.count + 1)
                
                self.itemArray.append(userSubmittedItem)
                gearTableView.reloadData()
                updateUI()
            }
        }
        
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
        cancelAction.setValue(UIColor.red, forKey: "titleTextColor")
        
        alertController.addAction(continueAction)
        alertController.addAction(cancelAction)
        
        self.present(alertController,
                     animated: true)
    }
    
    //MARK: - TableView Protocol Functions
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = gearTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! GearComponentTableViewCell
        cell.itemName.text = itemArray[indexPath.row].name
        cell.itemImage.image = itemArray[indexPath.row].image
        cell.itemWeight1.text = String("\(itemArray[indexPath.row].weight1)")
        cell.itemWeight2.text = String("\(itemArray[indexPath.row].weight2)")
        cell.itemQuanity.text = String("\(itemArray[indexPath.row].quantity)")
        cell.itemNotes.text = itemArray[indexPath.row].notes
        
        cell.tableViewCellPosition = indexPath.row
        
        return cell
    }
    
    //MARK: - Swipeable TableViewCell
    private func deleteItem(_ indexPath: IndexPath) {
        itemArray.remove(at: indexPath.row)
        gearTableView.reloadData()
        updateUI()
        print("Item Deleted")
    }
    
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let action = UIContextualAction(style: .normal, title: "Delete") { [weak self] (action, view, completionHandler) in
            self?.deleteItem(indexPath)
            completionHandler(true)
        }
        action.backgroundColor = .systemRed
        
        return UISwipeActionsConfiguration(actions: [action])
        
    }
}

extension GearComponentViewController: Stepper {
    
    func refreshTableViewCell() {
        print("arrayPosition: \(arrayPosition)")
//        itemArray[arrayPosition].quantity += 1
//        gearTableView.reloadData()
    }
    
    
    
    func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int) {
        
        if didIncrease {
            arrayPosition = userindexPath
            print("arrayPosition: \(arrayPosition)")
//            itemArray[userindexPath].quanity += 1
            print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
            print("increase selected")
            refreshTableViewCell()
        }else {
            arrayPosition = userindexPath
            print("arrayPosition: \(arrayPosition)")
//            itemArray[userindexPath].quanity -= 1
            print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
            print("decrease selected")
            refreshTableViewCell()
        }
    }
}

And here's an image of what my app looks like right now for reference.这是我的应用程序现在的样子以供参考。

The problem is in your delegate function.问题出在您的代表 function 中。 You try to delegate on a new instance of your GearComponentViewController().您尝试委托 GearComponentViewController() 的新实例。 Try replacing the var mainVC = GearComponentViewController() in your custom cell Class with尝试将自定义单元格 Class 中的var mainVC = GearComponentViewController()替换为

var delegate:Stepper?

and call the delegate with并用

delegate?.stepperWasPressed(didIncrease:...

also don't forget to register your delegate on your GearComponentViewController() in the cellForRow function like也不要忘记在 cellForRow function 中的 GearComponentViewController() 上注册您的委托,例如

cell.delegate = self

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 线程1:致命错误:索引超出范围。 不能从数组中快速获取值,控制台显示它们不是空数组 - Thread 1: Fatal error: Index out of range. Not getting a value from array in swift, console shows they're not empty arrays 线程 1:致命错误:当索引小于数组计数时索引超出范围 - Thread 1: Fatal error: Index out of range when index is less then array count 致命错误:附加数组时数组索引超出范围 - Fatal error: Array index out of range when appending array 在 SwiftUI 中访问数组中的元素时出现“致命错误:索引超出范围” - “Fatal error: Index out of range” when accessing elements in an array, in SwiftUI Swift致命错误:插入元素时数组索引超出范围 - Swift Fatal error: Array index is out of range when inserting an element 导致恐慌的原因:运行时错误:索引超出范围 [4],长度为 4,即使数组已初始化为动态数组 - What causes panic: runtime error: index out of range [4] with length 4 even though array is initialized as dynamic array Swift 数组:致命错误索引超出范围 - Swift array: fatal error index out of range 致命错误数组索引超出范围 - Fatal Error Array index out of Range 致命错误:从Internet下载数据时索引超出范围 - Fatal error: Index out of range when downloading data from the Internet Swift致命错误:数组索引超出范围 - Swift fatal error: array index out of range
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM