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

TableView重载分区崩溃求助:NSInternalInconsistencyException异常

问题分析

你的崩溃报错attempt to delete section 100, but there are only 7 sections before the update,核心原因是:

  1. prevIousSelection初始值设为了不存在的section编号100,当第一次执行折叠逻辑时,你尝试给这个无效的section设置状态,虽然字典允许存储该键,但这会干扰tableView的状态判断。
  2. 当展开新section时,你只重新加载了当前section,没有重新加载之前展开的section,导致tableView的行数缓存与数据源不一致,引发潜在的崩溃风险。
  3. 头部视图复用逻辑错误:你在viewForHeaderInSection中始终复用同一个headerViewMain实例,导致所有section的头部视图共享同一个对象,点击时可能传递错误的section编号。
修复代码

以下是修正后的完整代码:

class ExploreLocallyVc: UIViewController {
    @IBOutlet weak var tableView: UITableView?
    // 存储每个section的折叠状态,默认所有section都是收起(false)
    var sectionCollapsedStatus: [Int: Bool] = [:]
    // 初始值设为nil,表示之前没有选中任何section
    var previouslySelectedSection: Int? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView?.estimatedRowHeight = 80
        tableView?.rowHeight = UITableViewAutomaticDimension
        tableView?.sectionHeaderHeight = 60
        tableView?.separatorStyle = .none
        // 注册头部视图的nib,避免重复加载
        tableView?.register(UINib(nibName: "HeaderView", bundle: nil), forHeaderFooterViewReuseIdentifier: "HeaderView")
    }
}

extension ExploreLocallyVc: UITableViewDelegate, UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 7
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 如果字典中没有该section的状态,默认返回0(收起)
        guard let isExpanded = sectionCollapsedStatus[section], isExpanded else {
            return 0
        }
        return 4
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "q", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        // 复用头部视图,而不是每次创建同一个实例
        guard let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "HeaderView") as? HeaderView else {
            return UIView()
        }
        headerView.titleLabel?.text = "\(section)"
        // 根据当前section的状态设置箭头方向
        let isExpanded = sectionCollapsedStatus[section] ?? false
        headerView.arrowLabel?.transform = isExpanded ? CGAffineTransform(rotationAngle: .pi) : .identity
        headerView.section = section
        headerView.delegate = self
        return headerView
    }
}

extension ExploreLocallyVc: HeaderViewDelegate {
    func toggleSection(header: HeaderView, section: Int) {
        // 获取当前section的状态,默认是收起(false)
        let currentIsExpanded = sectionCollapsedStatus[section] ?? false
        
        if currentIsExpanded {
            // 折叠当前section
            sectionCollapsedStatus[section] = false
            tableView?.reloadSections(IndexSet(integer: section), with: .automatic)
        } else {
            // 展开当前section,同时折叠之前的section(如果存在且不是当前section)
            if let prevSection = previouslySelectedSection, prevSection != section {
                sectionCollapsedStatus[prevSection] = false
                // 重新加载之前的section,更新行数
                tableView?.reloadSections(IndexSet(integer: prevSection), with: .automatic)
            }
            // 展开当前section
            sectionCollapsedStatus[section] = true
            tableView?.reloadSections(IndexSet(integer: section), with: .automatic)
            // 更新之前选中的section为当前section
            previouslySelectedSection = section
        }
        
        print(sectionCollapsedStatus)
    }
}
关键修复点
  • 修正初始值问题:将prevIousSelection(重命名为previouslySelectedSection更清晰)的初始值设为nil,避免操作不存在的section。
  • 修复头部视图复用:使用tableView.dequeueReusableHeaderFooterView复用头部视图,每个section拥有独立的头部实例,避免section编号被覆盖。
  • 同步更新tableView状态:当展开新section时,不仅更新之前section的状态,还重新加载该section,确保tableView的行数与数据源一致。
  • 优化状态判断:通过空合运算符??处理字典中不存在的section状态,默认返回收起(false),逻辑更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:44:58