Słabe odwołania i przerywanie cykli (C++/CX)

W dowolnym systemie typów, który jest oparty na zliczaniu odwołań, odwołania do typów mogą tworzyć cykle — czyli jeden obiekt odwołuje się do drugiego obiektu, drugi obiekt odwołuje się do trzeciego obiektu i tak dalej, dopóki jakiś końcowy obiekt nie odwołuje się z powrotem do pierwszego obiektu. W cyklu nie można poprawnie usuwać obiektów, gdy liczba odwołań jednego obiektu stanie się zero. Aby ułatwić rozwiązanie tego problemu, język C++/CX udostępnia klasę Platform::WeakReference. WeakReference Obiekt obsługuje metodę Resolve, która zwraca wartość null, jeśli obiekt już nie istnieje lub zgłasza wyjątek Platform::InvalidCastException, jeśli obiekt jest aktywny, ale nie jest typu T.

Jednym ze scenariuszy, w którym WeakReference należy użyć, jest to, że this wskaźnik jest przechwytywany w wyrażeniu lambda używanym do definiowania programu obsługi zdarzeń. Zalecamy użycie nazwanych metod podczas definiowania procedur obsługi zdarzeń, ale jeśli chcesz użyć lambda dla programu obsługi zdarzeń lub jeśli musisz przerwać cykl zliczania odwołań w innej sytuacji, użyj polecenia WeakReference. Oto przykład:

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

}

Gdy program obsługi zdarzeń zgłasza błąd DisconnectedException, powoduje usunięcie programu obsługi z listy subskrybentów.