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 DisconnectedException
události způsobí, že událost odebere obslužnou rutinu ze seznamu odběratelů.