为了账号安全,请及时绑定邮箱和手机立即绑定

何时取消挂钩 Xamarin 自定义渲染器中的事件

何时取消挂钩 Xamarin 自定义渲染器中的事件

C#
开满天机 2022-01-15 19:39:19
众所周知,当在代码中连接事件处理时,我们冒着将对象留在内存中的风险,从而造成内存泄漏。为了实现一些特殊功能(禁用剪切和复制),我需要在 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łnieruk的建议,我在OldElement不为 null的检查中添加了 unhooking,但我从未看到任何证据证明这会被调用。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方法?
查看完整描述

1 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

在此处查看有关自定义渲染器的文章:实现视图 它包含自定义渲染器的 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 时挂钩它们。


至于评论中的后续问题(如果上面的第二个没有被触发,我们是否应该取消订阅):我的理解是这两个对象的生命周期(所以渲染器和本机控件)是相同的,在这种情况下没有需要手动取消订阅事件。如果我错了,请纠正我。


查看完整回答
反对 回复 2022-01-15
  • 1 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信