如何让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
相关产品推荐
相关产品推荐

