MVVM:使用闭包,无主或弱自我将View与ViewModel绑定?

时间:2018-05-20 08:03:55

标签: ios swift mvvm closures weak-references

我正在实现一个简单的Master-Detail应用程序,其中 Master viewController管理一个表视图,该视图显示对REST服务的调用结果。 详细信息 viewController管理一个视图,其中显示有关在 Master 中选择的项目的更多信息。常见情况。

我正在尝试应用MVVM模式。在 Master viewController中,我以这种方式创建并初始化viewModel

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()
}

我的问题是:在提供给viewModel的闭包中,self应该是weak还是unowned?我找到了一个实现类似于我的方案的示例,将其设置为weak,另一个将其设置为unowned,因此我不完全清楚。

3 个答案:

答案 0 :(得分:2)

[无主自我] 。这会告诉您的模型不要强烈引用ViewController

Apple文件明确指出:

  

“就像弱引用一样,无主参考并不能保持强势   坚持它所指的实例。然而,与弱参考不同,   假定无主参考值始终具有值“。

在您的情况下,始终有ViewController。因此,无主参考的好处是nonoptional。每次使用时都不需要打开包装

答案 1 :(得分:1)

unownedweak之间的区别在于weak被声明为可选,unowned不是{}。如果您知道自我不会nil使用unowned,如果您不知道:使用weak

答案 2 :(得分:1)

当您100%确定对象未被取消分配时,将使用

Unowned

weak然后您需要处理其引用计数问题。

viewModel.onModelChange = { [weak self] () in
    guard let strongSelf = self else { return }
    strongSelf.tableView.reloadData()
}

我通常这样做。然后,您可以保留self的强引用,以避免在块运行期间分配它。