You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITableViewCell删除行触发数组越界且列表不更新问题排查

问题分析与修复方案

核心问题

  1. 数据源不同步:删除scheduler中的元素后,未同步更新scheduleArray,导致tableView的行数计算(numberOfRowsInSection)仍基于旧的scheduleArray长度,但实际scheduler中的数组已缩短,最终触发数组越界。
  2. cellForRowAt中的不当操作:每次创建cell时都重新给scheduleArray赋值,且使用强制解包(scheduler![self.day])增加崩溃风险;同时存在不必要的DispatchQueue.main.async冗余代码。

具体修复步骤

1. 同步删除后的数据源

在删除成功的Alert回调中,删除scheduler元素后需同步更新scheduleArray,确保tableView的数据源统一:

deleteAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action: UIAlertAction!) in
    guard var daySchedule = self.scheduler?[self.day] else { return }
    // 确保索引合法,避免越界
    if tag < daySchedule.count {
        daySchedule.remove(at: tag)
        self.scheduler?[self.day] = daySchedule
        // 同步更新用于tableView展示的数据源
        self.scheduleArray = daySchedule
        self.scheduleView.reloadData()
    }
 }))

2. 优化cellForRowAt方法

  • 移除重复的scheduleArray赋值操作,避免每次创建cell都覆盖数据源
  • 替换强制解包为可选绑定,降低崩溃风险
  • 删除冗余的DispatchQueue.main.async(cellForRowAt本身在主线程执行)

修改后的cellForRowAt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = Bundle.main.loadNibNamed("schedulerCell", owner: self, options: nil)?.first as! scheduleCell
    cell.cellDelegate = self
    cell.editBtn.tag = indexPath.row
    cell.deleteSchedule.tag = indexPath.row
    
    // 安全获取当前行数据,处理数据不完整的情况
    guard let currentSchedule = self.scheduleArray?[indexPath.row], currentSchedule.count >= 2 else {
        cell.timeLabel1.text = ""
        cell.timeLabel2.text = ""
        return cell
    }
    
    cell.timeLabel1.text = currentSchedule[0]
    cell.timeLabel2.text = currentSchedule[1]
    return cell
}

3. 移除不必要的强制解包

在getData等方法中,用可选绑定替代强制解包,提升代码安全性:

func getData(){
    guard let getUrl = ScheduleURL?["GET"] else {
        print("GET 请求URL未配置")
        return
    }
    AFFunctions.getAFRequest(ofType: ScheduleResponse.self, url: getUrl) { responseData, statusCode in
        print(responseData?.data?.scheduler, statusCode)
        self.scheduler = responseData?.data?.scheduler
        DispatchQueue.main.async {
            // 初始化默认显示周日的日程
            self.showDetail(day: "Sunday", dayNum: 0)
        }
    }
}

额外建议

  • 给scheduleArray和scheduler设置初始空值,减少可选类型的处理成本:
    var scheduleArray: [[String]] = []
    var scheduler: [String: [[String]]] = [:]
    
  • 用数组映射简化daySelected中的日期匹配逻辑:
    let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
    self.dayNum = sender.tag
    self.day = days[min(sender.tag, days.count - 1)]
    

内容的提问来源于stack exchange,提问作者AbheshekSharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:15:35