3

我最近从 MVVMLight 3 升级到 4,并注意到我的命令坏了。事实证明,在新的 RelayCommand(在 3.5 版中实现)中使用弱引用导致我使用的代码构造失败。我知道有一些关于内存泄漏的弱引用的论点,我只是不明白。

这失败了:

private void InitCommand()
{
    Command = new SwitchMainGridCommand<SwitchMainGridToolViewModel>(this).Command;
}

失败是指当我使用已初始化并绑定到的 Command 属性时,它的支持方法已被垃圾收集,并且 Command 无法执行。有趣的是,Command 对象仍然存在,只是 SwitchMainGridCommand 上的支持属性现在消失了。在 RelayCommand 中的弱引用之前,Command 的引用也保持支持属性可用,即使 SwitchMainGridCommand 没有被显式保留。

这成功了:

SwitchMainGridCommand<SwitchMainGridToolViewModel> _refHolder = null;

private void InitCommand()
{
    _refHolder = new SwitchMainGridCommand<SwitchMainGridToolViewModel>(this);
    Command = _refHolder.Command;
}

在分配了 Command 的 ViewModel 上创建 _refHolder 类变量将阻止收集 _refHolder.Command 引用的方法/属性。

我想这是弱引用的期望行为,我只是不确定为什么需要它。

4

2 回答 2

1

这是 MSDN 上关于弱引用与强引用的文章: MSDN Goodness

于 2013-01-07T19:42:09.787 回答
0

也许,我重复一遍也许是因为这个原因:

在 MvvmLight 逻辑和其他 mvvm 样式中,ViewModel 使用定位器“链接”到视图。现在,当您的 xaml 页面向前移动到下一页时,上一页的 Vm 仍然存在,使用命令 weak 可以轻松释放内存。

第二个很简单,可以更好地控制对象的生命周期,让定位器唯一持有 Viewmodel 的引用,因此唯一可以决定何时何地释放

我希望这可以帮助你,我觉得如果 vm 仍然存在一段时间并不重要,主要是当你的软件不使用非常大的内存时。alloc 和 dealloc 影响严重影响软件的性能

于 2014-01-14T11:06:10.277 回答