다음을 통해 공유


약한 참조 및 순환 중단(C++/CX)

참조 횟수를 기반으로 하는 모든 형식 시스템에서는 형식 참조가 순환을 형성할 수 있는 문제가 있습니다. 즉, 하나의 개체가 두 번째 개체를 참조하고, 두 번째 개체가 세 번째 개체를 참조하는 식으로 최종 개체가 첫 번째 개체를 다시 참조할 때까지 진행됩니다. 이러한 순환에서는 한 개체의 참조 횟수가 0인 경우 개체를 올바르게 삭제할 수 없습니다. 이 문제를 해결하는 데 도움이 되도록 C++/CX는 Platform::WeakReference 클래스를 제공합니다. WeakReference 개체는 Resolve 메서드를 지원하며, 이 메서드는 개체가 더 이상 존재하지 않는 경우 null을 반환하고 개체가 활성 상태이지만 형식이 아닌 경우 Platform::InvalidCastException T을 throw합니다.

WeakReference 를 사용해야 하는 한 가지 시나리오는 this 포인터가 이벤트 처리기를 정의하는 데 사용되는 람다 식에서 캡처되는 경우입니다. 이벤트 처리기를 정의할 때 명명된 메서드를 사용하는 것이 좋지만 이벤트 처리기에 람다를 사용하려는 경우나 다른 상황에서 참조 횟수 순환을 끊어야 하는 경우에는 WeakReference를 사용하세요. 예를 들어 다음과 같습니다.

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

}

이벤트 처리기가 DisconnectedException을 throw하면 이벤트가 구독자 목록에서 처리기를 제거합니다.