.NET MAUI (Xamarin Forms) 页面/自定义视图何时被销毁?

发布于 2025-01-10 10:29:50 字数 3489 浏览 0 评论 0原文

我是 Xamarin/.NET MAUI 应用程序开发的新手。我开始为 Android 设备开发示例 .NET MAUI 应用程序。
我试图了解页面和我的自定义视图如何/何时被销毁(处置)。我阅读了一些网页,但我无法真正理解 .NET MAUI(或 Xamarin)中的工作原理。

我有三个页面:MainPageSecondPageTestMapPage
SecondPage 有一个导航到 TestMapPage 的按钮。它实例化一个 TestMapPage 对象并将其传递给 Navigation.PushAsync()
TestMapPage 包含一个自定义视图 TestMapView,它由我的自定义视图渲染器 TestMapViewRenderer 渲染。我在渲染器中创建一个 MapView 对象(来自 Naxam.Mapbox.Droid),并在 TestMapPage 中显示地图。地图出现在模拟器上并且工作正常。

我认为当我导航回 MainPage< 时,SecondPageTestMapPageTestMapView(以及 TestMapViewRenderer 中的所有对象)将被销毁/代码>。但是,当我在渲染器中的 Dispose() 上设置断点并导航回 中的 SecondPageMainPage 时,它永远不会被命中。

我的问题:

  1. SecondPageTestMapPageTestMapView 以及视图和视图渲染器中的所有其他对象是否像 MapboxMap > 当我返回 MainPage 时保存在某个地方?
  2. 页面和视图何时被销毁/处置?
  3. 如果这些页面对象保留在某个地方直到应用程序关闭,这是正常行为吗?
  4. 如果不是正常行为,我该如何解决?

我担心内存泄漏...

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    // ...
    private async void OnGoToSecondPageClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new SecondPage());
    }
}

SecondPage.xaml.cs

public partial class SecondPage : ContentPage
{
    // ...
    private async void OnMapShowClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new TestMapPage());
    }
}

TestMapPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MapTest"
             x:Class="MapTest.TestMapPage">
    <StackLayout Margin="5">
        <local:TestMapView
            x:Name="map"
            VerticalOptions="FillAndExpand" 
            HorizontalOptions="CenterAndExpand"/>
    </StackLayout>
</ContentPage>

TestMapView.cs

public class TestMapView : View { }

TestMapViewRenderer.cs

public partial class TestMapViewRenderer : ViewRenderer<TestMapView, Android.Views.View>
{
    private MapboxMap map;

    public TestMapViewRenderer(Context context) : base(context) {}

    protected override void OnElementChanged(ElementChangedEventArgs<TestMapView> e)
    {
        base.OnElementChanged(e);
        // ...
        if (Control == null)
        {
            var mapView = new MapView(Context);
            SetNativeControl(mapView);
            mapView.GetMapAsync(this);
        }
    }

    public void OnMapReady(MapboxMap map)
    {
        this.map = map;
        this.map.SetStyle(Resources.GetString(Resource.String.mapbox_style_satellite), this);
    }

    protected override void Dispose(bool disposing)
    {
        // A breakpoint never hits on this line. Why?
        base.Dispose(disposing);
    }
    // ...
}

I'm new to Xamarin/.NET MAUI application development. I started to develop a sample .NET MAUI application for Android device.
I'm trying to understand how/when a page and my custom view are destroyed (disposed of). I read some web pages but I can't really understand how things work in .NET MAUI (or Xamarin).

I have three pages: MainPage, SecondPage, TestMapPage.
SecondPage has a button that navigates to TestMapPage. It instantiates a TestMapPage object and passes it to Navigation.PushAsync().
TestMapPage contains a custom view TestMapView, which is rendered by my custom view renderer TestMapViewRenderer. I create a MapView object (from Naxam.Mapbox.Droid) in the renderer and show the map in TestMapPage. The map appears on the emulator and it works fine.

I thought that SecondPage, TestMapPage and TestMapView (and all the objects in TestMapViewRenderer) will be destroyed when I navigate back to MainPage. However, when I set a break point on Dispose() in the renderer and navigate back to SecondPage or MainPage in , it never gets hit.

My questions:

  1. Are the SecondPage, TestMapPage, TestMapView and all the other objects in the view and view renderer like MapboxMap kept somewhere when I go back to MainPage?
  2. When are pages and views destroyed/disposed of?
  3. If those page objects are kept somewhere until the application shuts down, is it normal behaviour?
  4. If not normal behaviour, how do I fix it?

I'm worried about memory leak...

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    // ...
    private async void OnGoToSecondPageClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new SecondPage());
    }
}

SecondPage.xaml.cs

public partial class SecondPage : ContentPage
{
    // ...
    private async void OnMapShowClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new TestMapPage());
    }
}

TestMapPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MapTest"
             x:Class="MapTest.TestMapPage">
    <StackLayout Margin="5">
        <local:TestMapView
            x:Name="map"
            VerticalOptions="FillAndExpand" 
            HorizontalOptions="CenterAndExpand"/>
    </StackLayout>
</ContentPage>

TestMapView.cs

public class TestMapView : View { }

TestMapViewRenderer.cs

public partial class TestMapViewRenderer : ViewRenderer<TestMapView, Android.Views.View>
{
    private MapboxMap map;

    public TestMapViewRenderer(Context context) : base(context) {}

    protected override void OnElementChanged(ElementChangedEventArgs<TestMapView> e)
    {
        base.OnElementChanged(e);
        // ...
        if (Control == null)
        {
            var mapView = new MapView(Context);
            SetNativeControl(mapView);
            mapView.GetMapAsync(this);
        }
    }

    public void OnMapReady(MapboxMap map)
    {
        this.map = map;
        this.map.SetStyle(Resources.GetString(Resource.String.mapbox_style_satellite), this);
    }

    protected override void Dispose(bool disposing)
    {
        // A breakpoint never hits on this line. Why?
        base.Dispose(disposing);
    }
    // ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘心安 2025-01-17 10:29:50

据我所知;

  1. 不,在每次导航上您都会创建新的页面实例,因此,页面由 .NET 本身创建并保存在内存中,一旦垃圾收集达到某个阈值,内存就会释放。在那之前,这些页面都在内存中,但并不意味着将来会使用。
  2. 当 GC 决定时,Xamarin/MAUI 并不关心视图。
  3. 不幸的是,是的。
  4. 这是正常的,您可以通过使用@ToolmakerSteve 所指的内容来克服。

as far as I know;

  1. No, on each navigation you create new page instances, so, the page is created and kept in memory by .NET itself, once garbage collection hits a certain threshold, the memory will be free. Until then, the pages are in memory, but not meant to use somewhen in the future.
  2. When GC decides, the Xamarin/MAUI doesn't care about views.
  3. Unfortunately, yes.
  4. It's normal, you can overcome by using what @ToolmakerSteve refers.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文