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

iOS UITableView自定义cell中label.isHidden异常行为如何解决?

异常产生原因

存在两个核心问题:

  1. UITableViewCell复用状态未重置:UITableView会复用已经创建的Cell来优化性能,上一次使用Cell时可能根据胜负情况显示了3个胜者/败者Label,本次给新行赋值时如果仅需要显示2个胜负Label,你只修改了前2个Label的显示状态和文字,剩余的Label依然保留上一次复用前的内容和显示状态,最终导致展示错乱。你遇到的第11局异常就是因为第11行的Cell复用了之前已经渲染过的旧Cell,未重置的旧Label内容直接显示了出来。
  2. Handler类设计存在逻辑隐患:你将winners、losers定义为Handler的成员属性,每次调用getWinners/getLosers方法只会往数组中追加内容,不会清空旧数据。虽然你当前在每次渲染Cell时都新建Handler实例暂时没有触发累加问题,但后续如果复用Handler实例会直接导致胜败数组长度异常,甚至触发数组越界崩溃。

修复方案

第一步:添加Cell复用重置逻辑

在自定义TableViewCell中重写prepareForReuse方法,每次Cell被复用时先重置所有Label的状态:

class TableViewCell: UITableViewCell {
    @IBOutlet var winnerNameLabels: [UILabel]!
    @IBOutlet var loserNameLabels: [UILabel]!
    @IBOutlet weak var roundLabel: UILabel!
    
    override func prepareForReuse() {
        super.prepareForReuse()
        // 重置胜者Label
        winnerNameLabels.forEach { label in
            label.isHidden = true
            label.text = nil
        }
        // 重置败者Label
        loserNameLabels.forEach { label in
            label.isHidden = true
            label.text = nil
        }
        roundLabel.text = nil
    }
}

第二步:优化Handler类实现

将胜败数组从成员属性改为方法内部局部变量,每次调用方法都生成新的空数组,避免数据累加:

class Handler {
    func getWinners(round: Int,dataBase: [Players]) -> [String] {
        var winners: [String] = []
        let filtered = dataBase.filter{ $0.round == round }
        filtered.forEach { if $0.winner { winners.append($0.name) } }
        return winners
    }
    
    func getLosers(round: Int,dataBase: [Players]) -> [String] {
        var losers: [String] = []
        let filtered = dataBase.filter{ $0.round == round }
        filtered.forEach { if $0.loser { losers.append($0.name) } }
        return losers
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:54:01