通过从数组中删除项目来删除tableView中的项目,并发生致命错误:索引超出范围

时间:2023-01-15 16:41:29

I am trying to remove an item from a public static array that is been shown in a tableview. The deletion is occuring in a different viewcontroller and when I try to enter that view controller the app crashes with the error of 'Index out of range'

我试图从tableview中显示的公共静态数组中删除一个项目。删除发生在另一个视图控制器中,当我尝试进入该视图控制器时,应用程序崩溃,错误为“索引超出范围”

this is where i delete the Item

这是我删除项目的地方

func removeItem (info:Dictionary<String, Any>){
    let stringKey = info[KEYS.stringKey] as! String
    for var i in 0 ..< ItemsViewController.itemVideosList.count {

        let current = ItemsViewController.itemVideosList[i]
        let currentStringKey = current[KEYS.stringKey] as! String

        if stringKey == currentStringKey {

            ItemsViewController.itemVideosList.remove(at: i)
            return
        }
    }

I call this method on a button click here:

我在按钮上点击此处调用此方法:

@IBAction func FavoriteAction(_ sender: Any) {


    if Flag {
        removeFromFavorite(info: songInfo)
        Flag = false
        }
    else {
        ItemsViewController.itemVideosList.insert(songInfo, at: 0)
        favFlag = true
    }
}

I am populating the table view in 'ItemsViewController' viewDidLoad with this method

我使用此方法填充'ItemsViewController'viewDidLoad中的表视图

func loadItems() {
    DispatchQueue.main.async {
        self.itemsTableView.reloadData()
    }
}

thanks

谢谢

1 个解决方案

#1


1  

You are trying to loop through when deleting. This leads to ItemsViewController.itemVideosList.count being invalid after your deletion.

您正在尝试在删除时循环。删除后,这会导致ItemsViewController.itemVideosList.count无效。

  1. You can solve your problem simply by adding a break instead of a return

    您可以通过添加中断而不是返回来解决您的问题

    if stringKey == currentStringKey {
        ItemsViewController.itemVideosList.remove(at: i)
        return
    }
    
  2. More importantly, you should not modify a collection while iterating it. This leads to undesired side effects. It's better to just store the indexToDelete and then delete it outside of loop.

    更重要的是,您不应在迭代时修改集合。这导致不希望的副作用。最好只存储indexToDelete,然后在循环外删除它。

    func removeItem (info:Dictionary<String, Any>){
    let indexToRemove = -1
    let stringKey = info[KEYS.stringKey] as! String
    for var i in 0 ..< ItemsViewController.itemVideosList.count {
    
        let current = ItemsViewController.itemVideosList[i]
        let currentStringKey = current[KEYS.stringKey] as! String
    
        if stringKey == currentStringKey {
            indexToDelete = i            
            break
        }
    }
    
    ItemsViewController.itemVideosList.remove(at: indexToDelete)
    }
    

Note:

注意:

You could make your iteration cleaner using higher-order functions like so:

您可以使用高阶函数使迭代更清晰:

var list = ["a", "b", "c"]

let index = list.index { (str) -> Bool in
    if str == "b" {
        return true
    }
    return false
}

#1


1  

You are trying to loop through when deleting. This leads to ItemsViewController.itemVideosList.count being invalid after your deletion.

您正在尝试在删除时循环。删除后,这会导致ItemsViewController.itemVideosList.count无效。

  1. You can solve your problem simply by adding a break instead of a return

    您可以通过添加中断而不是返回来解决您的问题

    if stringKey == currentStringKey {
        ItemsViewController.itemVideosList.remove(at: i)
        return
    }
    
  2. More importantly, you should not modify a collection while iterating it. This leads to undesired side effects. It's better to just store the indexToDelete and then delete it outside of loop.

    更重要的是,您不应在迭代时修改集合。这导致不希望的副作用。最好只存储indexToDelete,然后在循环外删除它。

    func removeItem (info:Dictionary<String, Any>){
    let indexToRemove = -1
    let stringKey = info[KEYS.stringKey] as! String
    for var i in 0 ..< ItemsViewController.itemVideosList.count {
    
        let current = ItemsViewController.itemVideosList[i]
        let currentStringKey = current[KEYS.stringKey] as! String
    
        if stringKey == currentStringKey {
            indexToDelete = i            
            break
        }
    }
    
    ItemsViewController.itemVideosList.remove(at: indexToDelete)
    }
    

Note:

注意:

You could make your iteration cleaner using higher-order functions like so:

您可以使用高阶函数使迭代更清晰:

var list = ["a", "b", "c"]

let index = list.index { (str) -> Bool in
    if str == "b" {
        return true
    }
    return false
}