簡體   English   中英

MVVM Light:如何取消注冊Messenger

[英]MVVM Light: how to unregister Messenger

我喜歡MVVM Light的Messenger及其靈活性,但是當我忘記明確取消注冊收件人時(在Silverlight 4中),我遇到了內存泄漏。

原因在這里解釋,但我很好,因為我認為明確取消注冊收件人是一個好習慣,而不是依賴於Messenger使用弱引用。 問題是說起來容易做起來難。

  • ViewModel很簡單:你通常可以完全控制它們的生命周期,只需要不再需要它們就可以Cleanup()它們。

  • 另一方面, 視圖更加棘手,因為它們是通過DataTemplates實例化和銷毀的。 對於前者 您可以將帶有MyViewItemsControl視為DataTemplate,綁定到ObservableCollection<MyViewModel> MyView控件由綁定引擎創建/收集,您無法在它們上手動調用Cleanup()。

我有一個解決方案,但想知道它是否是一個體面的模式或有更好的選擇。 我們的想法是從ViewModel發送一條特定的消息,告訴相關的View處理:

public class MyViewModel : ViewModelBase
{
    ...

    public override void Cleanup()
    {
        // unregisters its own messages, so that we risk no leak
        Messenger.Default.Unregister<...>(this);

        // sends a message telling that this ViewModel is being cleaned
        Messenger.Default.Send(new ViewModelDisposingMessage(this));

        base.Cleanup();
    }
}

public class MyView : UserControl, ICleanup
{
    public MyView()
    {
         // registers to messages it actually needs
         Messenger.Default.Register<...>(this, DoSomething);

         // registers to the ViewModelDisposing message
         Messenger.Default.Register<ViewModelDisposingMessage>(this, m =>
             {
                 if (m.SenderViewModel == this.DataContext)
                     this.Cleanup();
             });
    }

    public void Cleanup()
    {
        Messenger.Default.Unregister<...>(this);
        Messenger.Default.Unregister<ViewModelDisposingMessage>(this);
    }
}

因此,當您在viewModel上調用Cleanup()時,所有使用它作為DataContext的視圖也將執行其本地Cleanup()。

你怎么看? 我錯過了一些明顯的東西嗎

ViewModelLocator類有助於為視圖模型保留集中存儲。 您可以使用此類來幫助管理新版本並清理舊版本。 我總是通過定位器從視圖中引用我的viewmodel,所以我總是有可以運行的代碼來管理這些東西。 你可以試試。

同樣,我使用Cleanup方法調用Messenger.Unregister(this) ,它清除來自該對象的messenger的所有引用。 你必須每次都調用.Cleanup(),但這就是生活:)

我沒有使用MVVM Light(雖然我聽過很棒的東西)但是如果你想要一個使用WeakReferences的Messenger實現,請查看這里包含的Messenger http://mvvmfoundation.codeplex.com/

MVVM Light Messenger正在使用WeakAction(WeakReference)。 因此您無需顯式取消注冊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM