【问题标题】:MVVM: binding the View with the ViewModel with closures, unowned or weak self?MVVM:使用闭包、无主或弱自我将视图与 ViewModel 绑定?
【发布时间】:2018-10-30 03:57:26
【问题描述】:

我正在实现一个简单的 Master-Detail 应用程序,其中 Master viewController 管理一个表视图,该视图显示调用 REST 服务的结果。 Detail 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,所以我并不完全清楚。

【问题讨论】:

  • 如果没有self(视图控制器),您的viewModel 将永远存在。因此,self 永远不会为零,您可以放心地使用unowned

标签: ios swift mvvm closures weak-references


【解决方案1】:

[无主的自己]。这告诉你的模型不要对ViewController进行强引用

Apple 文件明确指出:

“像弱引用一样,无主引用不会保留强引用 坚持它所指的实例。然而,与弱引用不同的是, 假定无主引用始终具有值”。

在你的情况下,总是有ViewController。所以无主引用的好处是它是nonoptional。每次使用都不需要拆包

【讨论】:

  • 谢谢。正如我在问题下方的评论中所说,我认为这适用于我的特定场景,因为我的“主”视图控制器是根视图控制器,它的视图模型不会比它本身存在更长的时间。
【解决方案2】:

Unowned 在您 100% 确定对象不会被释放时使用。

weak 然后你需要处理它的引用计数问题。

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

我通常是这样做的。然后你持有self 的强引用以避免它在块运行期间被分配。

【讨论】:

  • 如果使用[weak self],那么self?.tableView.reloadData()就足够了
  • @MoayadAlkouz 如果您在块中有多个操作,则会出现问题。你永远不知道自己什么时候突然被压垮了。
【解决方案3】:

unownedweak 之间的区别在于 weak 被声明为 Optional 而 unowned 不是。如果你知道 self 不会是nil 使用unowned,如果你不知道:使用weak

【讨论】:

    猜你喜欢
    • 2016-08-15
    • 1970-01-01
    • 2011-01-31
    • 2016-12-02
    • 2023-04-06
    • 2010-12-07
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    相关资源
    最近更新 更多