1

我正在为我最近的项目使用 VIPER 架构。但我想知道如何实现 UITableView 数据源。

在 VIPER 中,视图是被动的。他们向 Presenter 发送事件,然后 Presenter 向 View 发送正确的 ViewData(ViewModel)。

所以我在 View 中存储了 tableView 的 ViewModels。(View 不会向 Presenter 询问数据。)

class View: UIViewController, UITableViewDataSource {
  var viewModels: [CellViewModelType] = []
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return viewModels.count
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let viewModel = viewModels[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIndetifier", for: indexPath)
    cell.configure(with: viewModel)
    return cell
  }
}

当用户在 tableView 中选择项目时,ViewdidSelectItemAt会向 Presenter 发送带有 indexPath 的事件。然后 Presenter 为事件决定适当的操作,推送 VC 或获取数据。

所以 Presenter 应该知道 ViewData(或 Real Data)。或者 Presenter 将事件传递给 Interactor,因为 Interactor 存储的是 Real Data。

这是我的同步困境。数据分布在 View、Presenter、Interactor。它们可能不同,因为 Real Data 可以在后台异步更改(如聊天应用程序)。因为锁定是完全不合适的,我如何确保 VIPER 架构中多个线程之间的状态数据完整性?

任何帮助将不胜感激。:D

4

2 回答 2

2

Presenter 应该存储 ViewModel,Interactor 应该存储实体。所以 View 应该像这样向演示者询问 ViewModel

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let viewModel = presenter.getViewModel(at: indexPath.row)
   let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIndetifier", for: indexPath)
   cell.configure(with: viewModel)
   return cell
}

当用户选择一个项目时,演示者可以决定调用交互器上的方法。所以模块状态只存储在Interactor中,而视图状态存储在Presenter中。视图不应该有任何状态

于 2018-03-08T16:47:46.200 回答
1

您是否担心 ViewModels 数组和 Presenter 或 Interactor 中的数据数组中的数据不一致?如果是这样,当 Interactor 获取新数据时,会将其传递给 Presenter。我更喜欢先将其作为 ViewModels 同步发送到 View,然后将其设置为 Presenter 的 Data 数组。当您didSelectCellAtIndexPath:使用 IndexPath 调用并将事件发送到 Presenter 时,从 Data 数组访问数据的额外检查是个好主意。

于 2017-09-11T17:54:38.983 回答