Когда снимать события в Xamarin Custom Renderers - PullRequest
0 голосов
/ 13 сентября 2018

Хорошо известно, что при подключении обработки событий в коде мы рискуем оставить объекты в памяти и, таким образом, создать утечку памяти.

Для достижения некоторых специальных функций (отключение копирования и копирования)) Мне нужно реализовать пользовательские рендеры на 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, однако я не сделалсмог надежно доказать, что это вызывается.

Обновление

Согласно Михал Жольнерук предложение Я добавил отцепку внутри проверки дляOldElement не равно нулю, однако я никогда не вижу доказательств того, что это вызывается.

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;
    }
}

Когда элементы управления удаляются из пользовательского интерфейса, следует ли очищать эти средства визуализации и, таким образом, запускать метод OnElementChanged?

1 Ответ

0 голосов
/ 13 сентября 2018

Взгляните на статью о пользовательских средствах рендеринга здесь: Реализация представления Содержит шаблон для метода 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 не является нулевым, и перехватывайте их, когда присутствует NewElement.

Что касается последующего вопроса в комментариях (мы должны отписаться, если второй, если выше, не был вызван): я понимаю, что время жизни обоихиз этих объектов (так что рендерер и собственный элемент управления) одинаковы, и в этом случае нет необходимости отписывать события вручную.Пожалуйста, поправьте меня, если я ошибаюсь.

...