我有一个页面“PageA”,它监听全局对象上的Changed事件。
该页面将添加到导航堆栈中,如下所示:
await Navigation.PushAsync(new PageA());
单击导航栏中的后退按钮即可删除该页面。
当我执行相同的x次时,我有x次PageA实例侦听Changed事件。所以PageA一次又一次地创建,但从未真正删除过。
单击后退按钮时如何真正摆脱PageA?
答案 0 :(得分:1)
你正在做什么的例子
public partial class MyPage : ContentPage
{
MyPage()
{
this.SomeEvent += SomeEventBeyondTheScopeOfThisPage();
}
protected override void OnDisappearing()
{
//You should add this
this.SomeEvent -= SomeEventBeyondTheScopeOfThisPage();
}
}
即使从导航堆栈弹出页面,也不会将引用从MyPage.SomeEvent删除到SomeEventBeyondTheScopeOfThisPage。因此,当垃圾收集器出现时,此页面将继续存在,并且将继续收听此事件。
只需在OnDisappearing中分离事件即可获得简单答案。您不会丢弃您只是将所有引用和事件分离到其范围之外的页面。更好的想法是使您的代码更加模块化,而不用担心分离事件。如果事件源来自页面本身,则不需要分离。
public partial class MyPage : ContentPage
{
MyPage()
{
this.SomeEvent += SomeEventWithinPagesScope();
}
private Task SomeEventWithinPagesScope()
{
//My cool event goes here
}
}
如果确实必须是全球性的话,另一个选择就是Messaging Center。我不相信你必须分离那些听众,但我可能是错的。
https://developer.xamarin.com/guides/xamarin-forms/messaging-center/
答案 1 :(得分:0)
另一个原因:NavigationPage。 CurrentNavigationTask.Result 仍然引用弹出的页面实例。这就是为什么GC不会收集它。除非你导航到其他页面。