我是否需要取消订阅 Click 事件以防止内存泄漏?
Do I need to unsubscribe Click event to prevent memory leaks?
我正在学习 Xamarin Android,我看到很多官方示例使用 lambdas 来订阅点击事件。像这样的东西:mButton.Click += (sender, args) => { ... }
很常见。我认为这种使用 lambda 的模式无法取消订阅事件。(如果我错了请纠正我:))
今天我阅读了这篇文档:Cross-Platform Performance - Unsubscribe from Events。它说我们应该取消订阅事件以防止内存泄漏。
那我就糊涂了。我应该取消订阅所有的点击事件吗?我觉得既然mButton是我的Activity的成员,那么在销毁我的Activity的时候,mButton也应该被销毁,所以没有必要取消订阅它的Click事件。是真的吗?如果是这样,那么在什么情况下我应该取消订阅活动?
谢谢!
绝对是!
为了防止内存泄漏,防止循环引用等很重要。花点时间搜索 SO,您会发现很多关于这个主题的内容。
我会说这取决于。只要没有保留引用并且垃圾收集器可以完成他的工作,您就不必这样做。但除此之外,最好这样做以防止内存泄漏。所以我更喜欢这样做。
要取消订阅 lambda 事件,只需将其存储在变量或字段中
EventHandler buttonOnClick = (sender, args) => button.Text = string.Format("{0} clicks!", count++);
button.Click += buttonOnClick;
button.Click -= buttonOnClick;
我通常是这样做的
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.LoginPage);
InflateViews ();
}
protected override void OnResume ()
{
base.OnResume ();
BindHandlers ();
}
protected override void OnPause ()
{
base.OnPause ();
UnBindHandlers ();
}
void InflateViews()
{
loginButton = FindViewById (Resource.Id.loginButton);
usernameField = FindViewById<EditText> (Resource.Id.userName);
passwordField = FindViewById<EditText> (Resource.Id.password);
forgotPassword = FindViewById (Resource.Id.forgotPassword);
}
void BindHandlers()
{
loginButton.Click+= LoginButton_Click;
forgotPassword.Click+= ForgotPassword_Click;
}
void ForgotPassword_Click (object sender, EventArgs e)
{
StartActivity (typeof(ForgotPasswordActivity));
}
void UnBindHandlers()
{
loginButton.Click-= LoginButton_Click;
forgotPassword.Click-= ForgotPassword_Click;
}
我正在学习 Xamarin Android,我看到很多官方示例使用 lambdas 来订阅点击事件。像这样的东西:mButton.Click += (sender, args) => { ... }
很常见。我认为这种使用 lambda 的模式无法取消订阅事件。(如果我错了请纠正我:))
今天我阅读了这篇文档:Cross-Platform Performance - Unsubscribe from Events。它说我们应该取消订阅事件以防止内存泄漏。
那我就糊涂了。我应该取消订阅所有的点击事件吗?我觉得既然mButton是我的Activity的成员,那么在销毁我的Activity的时候,mButton也应该被销毁,所以没有必要取消订阅它的Click事件。是真的吗?如果是这样,那么在什么情况下我应该取消订阅活动?
谢谢!
绝对是!
为了防止内存泄漏,防止循环引用等很重要。花点时间搜索 SO,您会发现很多关于这个主题的内容。
我会说这取决于。只要没有保留引用并且垃圾收集器可以完成他的工作,您就不必这样做。但除此之外,最好这样做以防止内存泄漏。所以我更喜欢这样做。
要取消订阅 lambda 事件,只需将其存储在变量或字段中
EventHandler buttonOnClick = (sender, args) => button.Text = string.Format("{0} clicks!", count++);
button.Click += buttonOnClick;
button.Click -= buttonOnClick;
我通常是这样做的
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.LoginPage);
InflateViews ();
}
protected override void OnResume ()
{
base.OnResume ();
BindHandlers ();
}
protected override void OnPause ()
{
base.OnPause ();
UnBindHandlers ();
}
void InflateViews()
{
loginButton = FindViewById (Resource.Id.loginButton);
usernameField = FindViewById<EditText> (Resource.Id.userName);
passwordField = FindViewById<EditText> (Resource.Id.password);
forgotPassword = FindViewById (Resource.Id.forgotPassword);
}
void BindHandlers()
{
loginButton.Click+= LoginButton_Click;
forgotPassword.Click+= ForgotPassword_Click;
}
void ForgotPassword_Click (object sender, EventArgs e)
{
StartActivity (typeof(ForgotPasswordActivity));
}
void UnBindHandlers()
{
loginButton.Click-= LoginButton_Click;
forgotPassword.Click-= ForgotPassword_Click;
}