何时取消Xamarin Custom Renderers中的事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了何时取消Xamarin Custom Renderers中的事件相关的知识,希望对你有一定的参考价值。
众所周知,当在代码中挂起事件处理时,我们冒着将对象留在内存中从而产生内存泄漏的风险。
为了实现一些特殊功能(禁用剪切和复制),我需要在UWP上实现自定义渲染器。虽然禁用剪切和复制与问题并不紧密相关,但我必须连接事件处理程序才能实现此目的。
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (this.Control == null) { return; }
this.Control.CopyingToClipboard += Control_CopyingToClipboard;
this.Control.CuttingToClipboard += Control_CuttingToClipboard;
}
private void Control_CuttingToClipboard(TextBox sender,
TextControlCuttingToClipboardEventArgs args)
{
args.Handled = true;
}
private void Control_CopyingToClipboard(TextBox sender,
TextControlCopyingToClipboardEventArgs args)
{
args.Handled = true;
}
题
解开这些事件处理程序以防止任何形式泄漏的正确位置是什么?
我注意到在IDisposable
平台命名空间中有一个VisualElementRenderer<TElement, TNativeElement>
实现而不是UWP
但是我无法可靠地证明这个被调用。
更新
根据MichałŻołnieruks的建议,我已经在检查中添加了unhooking,因为OldElement
不是null但是我从来没有看到任何证据证明这个被调用。
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (this.Control == null) { return; }
if (e.OldElement != null)
{
System.Debug.WriteLine("I NEVER SEE THIS");
this.Control.CopyingToClipboard -= Control_CopyingToClipboard;
this.Control.CuttingToClipboard -= Control_CuttingToClipboard;
}
if (e.NewElement != null)
{
this.Control.CopyingToClipboard += Control_CopyingToClipboard;
this.Control.CuttingToClipboard += Control_CuttingToClipboard;
}
}
如果从UI中删除控件,是否应清理这些渲染器,从而触发OnElementChanged
方法?
请在此处查看有关自定义渲染器的文章:Implementing a View它包含自定义渲染器的OnElementChanged方法的模板:
protected override void OnElementChanged (ElementChangedEventArgs<NativeListView> e)
{
base.OnElementChanged (e);
if (Control == null) {
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
}
if (e.OldElement != null) {
// Unsubscribe from event handlers and cleanup any resources
}
if (e.NewElement != null) {
// Configure the control and subscribe to event handlers
}
}
因此,当OldElement不为null时,您应取消挂钩事件,并在NewElement存在时挂钩它们。
至于评论中的后续问题(我们是否应该取消订阅,如果上面的第二个没有被触发):我的理解是这两个对象(如此渲染器和本机控制)的生命周期是相同的,在这种情况下没有需要手动取消订阅事件。如果我错了,请纠正我。
以上是关于何时取消Xamarin Custom Renderers中的事件的主要内容,如果未能解决你的问题,请参考以下文章
当动态更改背景时,Xamarin Custom Frame会导致Java.Lang.NullPointerException