TableView移除购物车项触发Index out of range崩溃问题排查
解决移除购物车条目时的Index Out of Range崩溃问题
你遇到的这个崩溃问题根源非常清晰:你直接用第一个TableView的indexPath.row(也就是2)去删除第二个视图的cartDetails数组元素,但这个数组里对应"dddd"条目的索引其实是1,数组索引不匹配自然就触发了越界错误。
你的代码逻辑错误在于:通过名称查询到购物车里有匹配条目后,想当然地认为第一个列表的索引和购物车数组的索引是对应的,但实际上两个数据源的索引完全没有关联关系,不能直接复用。
修正后的代码实现
我们需要先找到Core Data中匹配的商品对象,再定位它在cartDetails数组中的真实索引,之后再执行删除操作:
let context1 = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext let request = NSFetchRequest<NSFetchRequestResult>(entityName: "CartProducts") let targetProduct = newProdDetails[indexPath.row] // 先处理商品名称为空的边界情况 guard let targetName = targetProduct.name else { print("商品名称为空,无法执行删除操作") return } let predicate = NSPredicate(format: "name == %@", targetName) request.predicate = predicate request.fetchLimit = 1 do { // 获取Core Data中匹配的商品对象 let matchedObjects = try context1.fetch(request) as! [NSManagedObject] if let matchedProduct = matchedObjects.first { // 找到该对象在cartDetails数组中的真实索引 if let cartIndex = cartDetails.firstIndex(of: matchedProduct) { // 执行删除操作 context1.delete(matchedProduct) cartDetails.remove(at: cartIndex) try context1.save() // 别忘了刷新购物车视图的TableView // yourCartTableView.reloadData() } else { print("购物车数组中未找到匹配的商品对象") } } else { print("Core Data中未找到匹配的商品") } } catch let error as NSError { print("删除商品失败:\(error.localizedDescription)") }
关键优化点说明
- 索引匹配逻辑修正:不再复用第一个列表的索引,而是通过
firstIndex(of:)找到商品在购物车数组中的真实位置,彻底避免索引不匹配问题。 - 边界情况处理:增加了商品名称为空的判断,防止可选值解包崩溃。
- 错误信息打印:完善了各分支的调试信息,方便定位问题。
- 数据一致性保障:确保Core Data对象和数组元素操作同步,避免数据不一致。
额外建议
如果你的购物车允许添加多个同名商品,建议不要用name作为匹配条件,改用商品的唯一标识符(比如productId)来查询和匹配,这样能避免误删其他同名商品。
内容的提问来源于stack exchange,提问作者user8894520
相关产品推荐
相关产品推荐

