Search code examples
iosswiftmvvmclosuresweak-references

MVVM: binding the View with the ViewModel with closures, unowned or weak self?


I'm implementing a simple Master-Detail app where the Master viewController manages a table view which shows the results of a call to a REST service. The Detail viewController manages a view where I show more information about the item selected in the Master. Common scenario.

I'm trying to apply MVVM pattern. In the Master viewController, I create and initialize its viewModel this way:

lazy private var viewModel: ListViewModel = {
    return ListViewModel()
}()

override func viewDidLoad() {
    super.viewDidLoad()

    initViewModel()
}

private func initViewModel() {
    viewModel.onModelChange = { [weak self] () in
        DispatchQueue.main.async {
            self?.tableView.reloadData()
        }
    }

    viewModel.fetchData()
}

My question is: in the closure provided to the viewModel, should self be weak or unowned instead? I found an example implementing an scenario similar to mine that was setting it to weak, and another one setting it to unowned, so I'm not completely clear.


Solution

  • [unowned self]. This tells your model not to hold a strong reference to ViewController

    Apple document states it clearly that:

    “Like weak references, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is assumed to always have a value”.

    In your case, there is always be ViewController. So benefit of unowned reference is it’s nonoptional. No unwrap required each time it is used