【问题标题】: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 中删除它们

      【讨论】:

        【解决方案3】:

        使用 IOC 容器来维护所有 ViewModel 的单个实例。

        其中一个选项是使用 MVVM Light 附带的 SimpleIoc。

        Best tutorial to learn MVVMLight SimpleIoc

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-24
          • 1970-01-01
          • 2018-04-13
          • 2011-10-21
          • 2011-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多