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无效。
-
You can solve your problem simply by adding a break instead of a return
您可以通过添加中断而不是返回来解决您的问题
if stringKey == currentStringKey { ItemsViewController.itemVideosList.remove(at: i) return }
-
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无效。
-
You can solve your problem simply by adding a break instead of a return
您可以通过添加中断而不是返回来解决您的问题
if stringKey == currentStringKey { ItemsViewController.itemVideosList.remove(at: i) return }
-
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
}