我已经订阅了各种OnNavigatedTo
事件,例如
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Loaded += Screen_Loaded;
}
我尚未取消订阅此活动。不需要此页面时是否会导致任何内存问题?
No.在这种情况下,您无需取消订阅以避免内存泄漏。原因是您在 this
上订阅了一个事件。垃圾回收器必须标识这一点并释放对象。
但是,由于其他原因,我仍然会退订。例如,拥有平衡的资源使代码更易于阅读。另外,如果OnNavigatedTo被调用两次怎么办?(实际上不知道这是否会发生)然后,你将有两个对同一方法的订阅。有些人会争辩说,在这种情况下取消订阅是多余的代码并删除它。虽然这样是正确的,但我反对这样的论点。
您可以尝试此简短片段自己尝试一下。注意:除了了解本例中的 GC 外,切勿使用用户终结器或GC.Collect()
。
public class Program
{
private class Foo
{
public event EventHandler FooChanged;
~Foo()
{
Console.WriteLine("Foo was collected");
}
public void Bar()
{
FooChanged += UpdateUI;
}
private void UpdateUI(object sender, EventArgs e)
{
}
}
public static void Main(string[] args)
{
var foo = new Foo();
foo.Bar();
foo = null;
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("End of program");
Console.ReadKey();
}
}
是的,您必须取消订阅某些可能在地铁应用程序中自动触发的事件
例如:
诸如此类的事件
Window.Current.SizeChanged += Current_SizeChanged;
void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
//your code block contining various objects and logic
}
这些事件不受您的控制,因为它们在后台触发。任何可能与特定页面无关的事件(假设上述事件是在OnNavigatedTo事件中启动的),那么您必须在OnNavigatedFrom 等事件中取消订阅它
如需进一步说明,请初始化此事件
Window.Current.SizeChanged += Current_SizeChanged;
只需保留一个断点并将窗口大小从横向更改为贴靠模式,除非您尚未取消订阅该事件,否则此事件将触发。
请记住:
- 您可能会意外地多次订阅事件(使用 -= 来避免这种情况)。
- 如果事件处理程序是来自其他某个对象的方法,则在订阅事件的方法之前,不会对该对象进行垃圾回收。