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

如何判断UITableViewCell是否已被出队或不在屏幕显示?

实现方案
  • 利用UITableViewCell自带的复用生命周期方法prepareForReuse,这个方法会在cell即将被回收复用时触发,此时直接停止定时器即可。
  • 也可以重写didMoveToWindow方法,当self.window == nil时说明cell已经离开屏幕,此时停止定时器;当self.window != nil时如果定时器未运行,可以重启定时器。
  • 额外优化:原有Timer的写法会强持有Cell,导致Cell无法正常释放,建议改用带weak修饰的Block版本Timer避免循环引用。

修改后参考代码:

class TeamBattleTableViewCell: UITableViewCell {    
    @IBOutlet weak var resultsSubtitleLabel: MantisLabel!
    var timer: Timer?
    
    func updateDisplay() {
        updateTime()
        // 先停掉旧定时器避免重复创建
        timer?.invalidate()
        // 改用Block版本Timer,加weak self避免循环引用
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
            self?.updateTime()
        }
    }
    
    @objc func updateTime() {
        let man = TeamBattleManager.get()
        let d = man.end_date.offsetFrom(date: Date())
        resultsSubtitleLabel.text = d+" remaining"
    }
    
    // 重写复用方法,cell被回收时停止定时器
    override func prepareForReuse() {
        super.prepareForReuse()
        timer?.invalidate()
        timer = nil
    }
    
    // 可选:cell离开/进入屏幕时自动处理定时器启停
    override func didMoveToWindow() {
        super.didMoveToWindow()
        if window == nil {
            // 离开屏幕,停止定时器
            timer?.invalidate()
            timer = nil
        } else {
            // 进入屏幕,按需重启定时器
            updateDisplay()
        }
    }
}

如果你更倾向于在ViewController层面控制,也可以搭配UITableView的两个代理方法实现:在tableView(_:willDisplay:forRowAt:)里调用cell的updateDisplay启动定时器,在tableView(_:didEndDisplaying:forRowAt:)里调用cell的定时器停止逻辑,两种方案都可以满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:36:04