Sdílet prostřednictvím


Slabé odkazy a narušené cykly (C++/CX)

V libovolném systému typů, který je založen na počítání odkazů, mohou odkazy na typy tvořit cykly – to znamená, že jeden objekt odkazuje na druhý objekt, druhý objekt odkazuje na třetí objekt a tak dále, dokud se některý konečný objekt nebude odkazovat zpět na první objekt. V cyklu nelze správně odstranit objekty, když se počet odkazů jednoho objektu změní na nulu. Pro usnadnění řešení tohoto problému poskytuje C++/CX třídu Platform::WeakReference. Objekt podporuje Resolve metoda, která vrátí hodnotu null, pokud objekt již neexistuje, nebo vyvolá Platform::InvalidCastException, pokud je objekt aktivní, ale není typu T. WeakReference

Jeden scénář, ve kterém WeakReference se musí použít, je, když this je ukazatel zachycen ve výrazu lambda, který slouží k definování obslužné rutiny události. Při definování obslužných rutin událostí doporučujeme použít pojmenované metody, ale pokud chcete pro obslužnou rutinu události použít lambda nebo pokud je nutné přerušit cyklus počítání odkazů v jiné situaci, použijte WeakReference. Tady je příklad:

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

}

Při vyvolání obslužné rutiny DisconnectedExceptionudálosti způsobí, že událost odebere obslužnou rutinu ze seznamu odběratelů.