Dela via


Svaga referenser och icke-bakåtkompatibla cykler (C++/CX)

I alla typer av system som baseras på referensräkning kan referenser till typer bilda cykler, det vill sa att ett objekt refererar till ett andra objekt, det andra objektet refererar till ett tredje objekt och så vidare tills något slutligt objekt refererar tillbaka till det första objektet. I en cykel kan objekt inte tas bort korrekt när ett objekts referensantal blir noll. För att hjälpa dig att lösa det här problemet tillhandahåller C++/CX klassen Platform::WeakReference. Ett WeakReference objekt stöder metoden Resolve , som returnerar null om objektet inte längre finns, eller genererar en Plattform::InvalidCastException om objektet är vid liv men inte är av typen T.

Ett scenario där WeakReference måste användas är när pekaren this avbildas i ett lambda-uttryck som används för att definiera en händelsehanterare. Vi rekommenderar att du använder namngivna metoder när du definierar händelsehanterare, men om du vill använda en lambda för händelsehanteraren, eller om du måste bryta en referensräkningscykel i någon annan situation, använder du WeakReference. Här är ett exempel:

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

}

När en händelsehanterare genererar DisconnectedExceptionfår händelsen att ta bort hanteraren från prenumerantlistan.