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

时间:2017-08-08 08:16:31

标签: ios arrays swift uitableview

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

这是我删除项目的地方

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
        }
    }

我点击按钮点击此方法:

@IBAction func FavoriteAction(_ sender: Any) {


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

我在&#39; ItemsViewController&#39;中填充表格视图viewDidLoad使用此方法

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

感谢

1 个答案:

答案 0 :(得分:1)

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

  1. 您只需添加分钟而不是返回

    即可解决问题
    if stringKey == currentStringKey {
        ItemsViewController.itemVideosList.remove(at: i)
        return
    }
    
  2. 更重要的是,在迭代时不应修改集合。这导致不希望的副作用。最好只存储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)
    }
    
  3. 注意:

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

    var list = ["a", "b", "c"]
    
    let index = list.index { (str) -> Bool in
        if str == "b" {
            return true
        }
        return false
    }