Application.Current.MainPage与Navigation.PushAsync()与Navigation.PushModalAsync() [英] Application.Current.MainPage vs Navigation.PushAsync() vs Navigation.PushModalAsync()

查看:471
本文介绍了Application.Current.MainPage与Navigation.PushAsync()与Navigation.PushModalAsync()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发不需要后退按钮的Xamarin Forms App(PCL).该应用程序具有三个页面:一个SplashScreenPage来加载数据,一个LoginPage(如果用户需要登录)和一个RootPage(即一个MasterDetailPage).我想知道在页面之间导航的最佳选择是什么(例如,避免内存泄漏):

I'm developing an Xamarin Forms App (PCL) that does NOT need a back button. That app has three pages : a SplashScreenPage to load data, a LoginPage if the user needs to login and a RootPage which is a MasterDetailPage. I was wondering what was the best option to navigate between pages (to avoid memory leaks for example):

第一个解决方案:

Application.Current.MainPage = new ContentPage();

第二个解决方案:

Navigation.PushAsync(new NavigationPage(new ContentPage()));

然后

NavigationPage.SetHasNavigationBar(this, false);
ClearNavigationStack();

第三种解决方案

await Navigation.PushModalAsync(new NavigationPage(new ContentPage()));

然后

NavigationPage.SetHasNavigationBar(this, false);
ClearModalStack();

推荐答案

如@ will-decter所述,如果正确实施,上述解决方案都不会导致内存泄漏.

As describe by @will-decter none of the above solutions could cause memory leaks if implemented correctly.

您可以使用任何上述解决方案.通常,您无需执行任何操作即可清除上一页.垃圾收集器会自动为您执行此操作(不是立即执行,而是根据某些条件在一段时间后执行).考虑第一个解决方案:

You can use any of the above solutions. And generally you need not to do anything to clear previous page. Garbage Collector automatically do that for you (Not immediately but after some time based on some condition). Consider first solution:

Application.Current.MainPage = new Page1();

现在,如果您要像这样分配新页面.

Now if you assign new page like this.

Application.Current.MainPage = new Page2();

由于不再使用Page1,因此当GC尝试回收一些内存时,GC将在一段时间后收集Page1对象.您也可以使用GC.Collect()强制GC立即回收内存,但是由于GC.Collect()操作非常昂贵,因此我建议您不要从代码中调用它,而应该对代码进行优化,所以不需要调用它

As Page1 is no longer in use, GC will collect Page1 object after some time when GC try to reclaim some memory. You can also use GC.Collect() to force GC to reclaim memory immediately but as GC.Collect() operation is expensive so I would suggest you should not call it from your code rather optimize your code so don't need to call it.

但是,如果您的页面订阅了一个事件并且没有取消订阅该事件,则在这种情况下,即使您调用GC.Collect()方法,GC也无法收集该页面.因此,请确保您取消订阅任何已订阅的事件,例如:

But if your page is subscribe to an event and does not unsubscribe it then in that case GC cannot collect that the page even if you call GC.Collect() method. So make sure that you unsubscribe any subscribed event like this:

public class MainPage : ContentPage
{
     protected override void OnAppearing()
     {
         base.OnAppearing();
         MyEntry.TextChanged += MyEntry_TextChanged;
     }

     protected override void OnDisappearing()
     {
         base.OnDisappearing();
         MyEntry.TextChanged -= MyEntry_TextChanged;
     }
}

(如果事件是从xaml订阅的,则可以跳过取消订阅,因为在这种情况下Xamarin Form使用WeakReference)

(You can skip unsubscibe if event was subscribe from xaml as in that case Xamarin Form uses WeakReference)

这将确保在需要时由GC收集MainPage.

This will ensure MainPage is collected by GC when needed.

我建议阅读文章,以更好地了解GC在Xamarin中的工作方式以及如何提高应用程序性能.

I would suggest to read this article to get better insight how GC works in Xamarin and how can you increase your application performance.

https://developer.xamarin.com/指南/跨平台/部署,_testing,_and_metrics/memory_perf_best_practices/

这篇关于Application.Current.MainPage与Navigation.PushAsync()与Navigation.PushModalAsync()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆