9

我很清楚 Swift 中值类型和引用类型之间的区别,并且知道值类型被设计为不可变的用法。但结构尤其具有自我变异的能力,这是我关心的问题。如何有效地使用这些变异的结构值类型,以便它们保持它们的状态或变化。

我的问题是,在 iOS 应用程序的 MVVM 设计中,视图模型应该是类还是结构?由于视图模型包含模型/模型列表,并且这些模型实例会随着时间而变化(例如,视图模型从 Web 服务请求中获取更多模型实例并添加到它的模型数组中),视图控制器的视图模型如何更新这种变化。这是一个伪示例,但首先是一些注意事项和简要说明:

  • 我在这里没有使用任何绑定。(没有 RxSwift)。
  • 没有 KVO,我正在使用委托或完成处理程序设计。

例子:

  • 视图控制器具有视图模型的实例。当它出现时,它要求视图模型从 Web 服务中获取数据。
  • 查看模型触发服务,并在完成处理程序闭包中获得响应
  • 在这个闭包视图模型中,将一些模型实例添加到它的模型数组中。
  • 视图模型调用视图控制器的完成处理程序来通知服务请求的成功或错误。
  • 视图控制器对视图模型进行一些验证,然后相应地执行 UI 操作。

查看型号:

 struct DummyViewModel {

  private var ints:[Int] = []

  var count: Int {
    return ints.count
  }

  init() {}

  mutating func fetchData(completionHandler:(NSError? ) -> Void) {
    Networking.getDataFromRemote() { response in
          self.ints.append(1)
          completionHandler(nil)
    }
  }
}

视图控制器:

class DummyViewController: UIViewController{
  private var dummyViewModel: DummyViewModel?

  override func viewDidLoad() {
    super.viewDidLoad()

    /// Setup the view model
    dummyViewModel = DummyViewModel()
  }

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    loadData()
  }
}

private extension DummyViewController {

  func loadData() {
    dummyViewModel?.fetchData { error in
        if self.dummyViewModel?.count > 0 {
          print("View model updated")
        } else {
          print("View model is still same")
        }
      }
    }
}

在上面的代码中,当视图模型获得响应时,它会将数据添加到它的数组中,但是该更改永远不会传递给视图控制器,因为在闭包内部,更新的是视图模型的副本而不是视图控制器的模型。所以问题是这个变化是如何传递给视图控制器的?

我是否应该从闭包中返回更新的视图模型实例,并且在视图控制器的闭包中更新它是视图模型的实例。但这也不会像在视图控制器关闭中那样工作,我也会更新视图模型的副本??

我们应该如何处理?一种选择是让视图模型成为一个类,这样一切都是参考,我们在任何地方都更新同一个实例。但是由于视图模型和模型会发生同样的事情,模型也将是类。由于我们的应用程序的主要部分是视图控制器,因此我们创建的所有视图模型和模型都是类。所以我们真的没有在这里使用值类型的力量。

有什么建议么?

4

0 回答 0