Disposal of objects in Xamarin.Forms

I am looking for the right way to recycle objects in a Xamarin Forms application. I am currently using the XAML and MVVM coding style. Then, from my view model, I get a reference to a one-time object through the built-in service locator ( DependencyService ). Ideally, I would have to call Dispose () on the objects from my view model, but other solutions such as joining ContentPage.OnDisappearing and NavigationPage.Popped may be feasible.

+4
source share
3 answers

We were spared the exception of objects in Forms when bindings to lists or labels changed values ​​when deleting pages / fragments. I assume that you could manage the objects in the ViewModel in the same place where we removed the bindings.

protected override void OnParentSet()
{
    base.OnParentSet();

    if (Parent == null)
    {
        //Clear a bunch of bindings or dispose of ViewModel objects 
        BindingContext =
            _listView.ItemsSource = null;
    }
}
+3
source

I had almost the same requirement a couple of weeks ago. I wanted to make sure that event subscriptions in my view models would be unsubscribed when the page was closed. After many studies, my conclusion was that the easiest solution was to use the ContentPage.OnDisappearing method.

, , , ViewModel, , , ViewModel , . , OnAppearing OnDisappearing ( , , , , IPropertyNotify - ).

public class ViewModelBase
{
    /// <summary>
    /// Called when page is appearing.
    /// </summary>
    public virtual void OnAppearing()
    {
        // No default implementation. 
    }

    /// <summary>
    /// Called when the view model is disappearing. View Model clean-up should be performed here.
    /// </summary>
    public virtual void OnDisappearing()
    {
        // No default implementation. 
    }
}

ContentPage OnAppearing OnDisappearing, .

public class PageBase : ContentPage
{
    /// <summary>
    /// Performs page clean-up.
    /// </summary>
    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        var viewModel = BindingContext as ViewModelBase;

        // Inform the view model that it is disappearing so that it can remove event handlers
        // and perform any other clean-up required..
        viewModel?.OnDisappearing();
    }

    protected override void OnAppearing()
    {
        // Inform the view model that it is appearing
        var viewModel = BindingContext as ViewModelBase;

        // Inform the view model that it is appearing.
        viewModel?.OnAppearing();
    }
}

, , , PageBase:

<?xml version="1.0" encoding="utf-8" ?>
<pages:PageBase xmlns="http://xamarin.com/schemas/2014/forms"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          xmlns:controls="clr-namespace:Forms.App.Controls;assembly=Forms.App"
          xmlns:converters="clr-namespace:Forms.App.Converters;assembly=Forms.App"
          xmlns:pages="clr-namespace:Forms.App.Pages;assembly=Forms.App"
          x:Class="Forms.App.Pages.LogonPage"
          NavigationPage.HasNavigationBar="False"
          Title="Logon">

ViewModel OnDisappearing :

public class FormViewModel : ViewModelBase
{
    public override void OnDisappearing()
    {
        base.OnDisappearing();

        // Dispose whatever objects are neede here
    }
}

, - , OnDisappearing , ( ). , , , . , - , . , OnAppearing OnDisappearing.

, !

+2

, IDisposable. , BindingContext , .

, OnParentSet, NULL, , .

The SafeContentPage class can be used instead of ContentPage. Iff Binding Context supports IDisposable, it will automatically try to remove the binding context.

public class SafeContentPage : ContentPage
{
    protected override void OnParentSet()
    {
        base.OnParentSet();
        if (Parent == null)
            DisposeBindingContext();
    }

    protected void DisposeBindingContext()
    {
        if (BindingContext is IDisposable disposableBindingContext) {
            disposableBindingContext.Dispose();
            BindingContext = null;
        }
    }

    ~SafeContentPage()
    {
        DisposeBindingContext();
    }
}

The OnDisappearing method is not reliable technical, because there are differences in the platform in terms of when it is called, and just because the page has disappeared does not mean that its viewing model is no longer needed.

0
source

Source: https://habr.com/ru/post/1675159/


All Articles