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

如何让TableView在运行时正确重载对应数据?

问题根源与修复方案

核心问题:ViewModel 实例重复创建

你在两个独立位置分别创建了 TVMainViewControllerViewModel 的实例:

  • TVMainViewController 内的 private let viewModel = TVMainViewControllerViewModel()
  • TVMainViewControllerView 内的 private var viewModel = TVMainViewControllerViewModel()

这是两个完全无关的对象!弹窗页面修改的是 ViewController 持有的 viewModel 的 selectedList,但 View 始终使用自己创建的 viewModel 实例,所以 View 的 didLoadCoins 方法中打印的 selectedList 还是初始值,TableView 自然不会更新。

修复步骤

1. 移除 View 内部的 ViewModel 实例,改为外部传入

修改 TVMainViewControllerView,将内部 viewModel 改为外部注入模式:

final class TVMainViewControllerView: UIView, TVMainViewControllerViewModelDelegate {
    
    // 移除自行创建的 viewModel,改为可选变量等待外部赋值
    private var viewModel: TVMainViewControllerViewModel?
    var delegate: TVMainViewControllerViewButtonDelegate?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupTableView()
        setupUI()
        // 数据请求逻辑移至外部,避免重复初始化
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 添加配置方法,接收外部传入的 viewModel
    func configure(with viewModel: TVMainViewControllerViewModel) {
        self.viewModel = viewModel
        self.viewModel?.delegate = self
        // 启动数据请求
        Task {
            await viewModel.decodeData {
                self.viewModel?.delegate?.didLoadCoins()
            }
        }
    }
    
    private func setupTableView() {
        tableView.register(VTMainTableViewCell.self, forCellReuseIdentifier: Constants.mainTableViewCell)
        // 延迟设置 dataSource,待 viewModel 传入后再绑定
    }
    
    func didLoadCoins() {
        guard let viewModel = viewModel else { return }
        print(viewModel.selectedList)
        tableView.dataSource = viewModel
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
    
    // 其他代码保持不变
}

2. 在 ViewController 中传递同一个 ViewModel 实例给 View

修改 TVMainViewController 的 viewDidLoad 方法,调用 View 的配置方法传入自身持有的 viewModel:

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.isNavigationBarHidden = true
    mainView.delegate = self
    // 传递同一个 viewModel 实例给 View
    mainView.configure(with: viewModel)
    setupUI()
}

3. 清理冗余的委托设置

  • 移除 TVMainViewControllerView 初始化方法中的 viewModel.delegate = self(已在 configure 方法中处理)
  • 移除 TVMainViewController 中的 viewModel.delegate = mainView(View 会在配置时自行绑定)

额外优化建议

  • decodeData 方法中循环同步发起多个网络请求,可能导致并发过高被限流,建议改用 async/await 串行执行或控制并发数
  • calculateDailyTurnoverRatio 中每次重置的 coinLiquidityList 未被实际使用,可直接移除该变量减少冗余代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:56:04