【问题标题】:multiple instances of view and view model in memory内存中视图和视图模型的多个实例
【发布时间】:2014-08-15 00:56:34
【问题描述】:
我们有一个 windows phone 8 应用程序,其中我们使用 mvvm light 具有四个、五个视图和大约相同数量的视图模型。有一天,我们观察到应用程序的大小随着使用量的增加而增加,最终超过 100 mb 并最终崩溃。经过大量测试,我们能够理解的是,每次导航到视图时,都会创建其实例并存储在内存中。据观察,视图和视图模型的所有实例都存在于内存中,从而增加了 ram 上的空间。我们还通过在视图类和视图模型上定义终结器来确认这一点,在关闭应用程序时,终结器被调用的次数与页面导航到的次数完全相同。我们将视图的数据上下文绑定到 xaml 中的相应视图模型。其中一个主视图有一个广告控件,因此如果用户多次导航到该视图,尺寸会增长得非常快。如何解决这个问题。我无法理解的是,一旦用户按下后退按钮,视图应该被破坏,但这并没有发生。任何帮助将非常感激。
【问题讨论】:
标签:
windows-phone-8
mvvm
memory-leaks
mvvm-light
【解决方案1】:
我们通过将以下代码行添加到代码后面找到了解决方案。
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Messenger.Default.Unregister(this);
if (e.NavigationMode == NavigationMode.Back)
{
DataContext = null;
}
}
我们在上面所做的是取消注册页面的所有消息处理程序并将 DataContext 分配给 null。在我们的例子中,datacontext 仅在 xaml 中分配,并且消息处理程序在页面的 OnNavigatedTo 事件中注册。但是仍然不清楚的是,在从页面导航回来时,页面对象应该已经自动死亡。并且应该将这行代码添加到所有 mvvm 轻项目页面中,如果是这样,那么为什么它不是常见的做法。
【解决方案2】:
您泄漏视图内存的原因是因为您以某种方式从视图内部订阅了 ViewModel 的事件。要么将这些订阅重构为 WeakEvent 订阅,要么在 OnNavigatedFrom 中删除它们