Partilhar via


Referências fracas e ciclos de quebra (C++/CX)

Em qualquer sistema de tipos baseado na contagem de referências, as referências a tipos podem formar ciclos, ou seja, um objeto se refere a um segundo objeto, o segundo objeto se refere a um terceiro objeto e assim por diante até que algum objeto final se refira ao primeiro objeto. Em um ciclo, os objetos não podem ser excluídos corretamente quando a contagem de referência de um objeto se torna zero. Para ajudá-lo a resolver esse problema, o C++/CX fornece a classe Platform::WeakReference. Um WeakReference objeto suporta o método Resolve , que retorna null se o objeto não existir mais, ou lança um Platform::InvalidCastException se o objeto estiver vivo, mas não for do tipo T.

Um cenário no qual WeakReference deve ser usado é quando o ponteiro é capturado this em uma expressão lambda usada para definir um manipulador de eventos. Recomendamos que você use métodos nomeados ao definir manipuladores de eventos, mas se quiser usar um lambda para seu manipulador de eventos — ou se tiver que quebrar um ciclo de contagem de referência em alguma outra situação — use WeakReference. Aqui está um exemplo:

using namespace Platform::Details;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Controls;

Class1::Class1()
{
    // Class1 has a reference to m_Page
    m_Page = ref new Page();

    // m_Page will have a reference to this Class1
    // so create a weak reference to this
    WeakReference wr(this);
    m_Page->DoubleTapped += ref new DoubleTappedEventHandler(
        [wr](Object^ sender, DoubleTappedRoutedEventArgs^ args)
    {
       // Use the weak reference to get the object
       Class1^ c = wr.Resolve<Class1>();
       if (c != nullptr)
       {
           c->m_eventFired = true;
       }
       else
       {
           // Inform the event that this handler should be removed
           // from the subscriber list
           throw ref new DisconnectedException();
       }
    });
}

}

Quando um manipulador de DisconnectedExceptioneventos lança , ele faz com que o evento remova o manipulador da lista de assinantes.