Bagikan melalui


Referensi lemah dan siklus pemecah (C++/CX)

Dalam sistem jenis apa pun yang didasarkan pada penghitungan referensi, referensi ke jenis dapat membentuk siklus—yaitu, satu objek mengacu pada objek kedua, objek kedua mengacu pada objek ketiga, dan sebagainya sampai beberapa objek akhir merujuk kembali ke objek pertama. Dalam siklus, objek tidak dapat dihapus dengan benar ketika jumlah referensi satu objek menjadi nol. Untuk membantu Anda mengatasi masalah ini, C++/CX menyediakan Kelas Platform::WeakReference. Objek WeakReference mendukung metode Resolve, yang mengembalikan null jika objek tidak ada lagi, atau melempar Platform::InvalidCastException jika objek masih hidup tetapi bukan tipe T.

Salah satu skenario di mana WeakReference harus digunakan adalah ketika penunjuk this diambil dalam ekspresi lambda yang digunakan untuk menentukan penanganan aktivitas. Kami menyarankan agar Anda menggunakan metode bernama saat menentukan penanganan aktivitas, tetapi jika Anda ingin menggunakan lambda untuk penanganan aktivitas Anda—atau jika Anda harus memutuskan siklus penghitungan referensi dalam beberapa situasi lain—gunakan WeakReference. Berikut contohnya:

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

}

Ketika penanganan aktivitas melemparkan DisconnectedException, itu menyebabkan peristiwa menghapus handler dari daftar pelanggan.