← SEARCHABLE ARCHIVE
Unreal Engine · 2026-07-04

Widget 생명주기와 Delegate 중복 연결

NativeConstruct가 다시 호출될 때 생기는 문제

INTERACTIVE READING MODE →

본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.

UUserWidget::NativeConstruct()는 객체가 처음 만들어질 때 딱 한 번만 호출된다고 생각하기 쉽다. 하지만 위젯이 화면에서 제거되었다가 다시 추가되면 Construct가 다시 호출될 수 있다.

Delegate가 중복 연결될 수 있다

void UDailyProblemWidget::NativeConstruct()
{
    Super::NativeConstruct();

    SubmitButton->OnClicked.AddDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );
}

Construct가 두 번 호출되면 같은 버튼 클릭에 함수가 두 번 실행될 수 있다. 저장, 재화 차감, 노드 생성 같은 로직이라면 실제 데이터가 중복 처리된다.

ProjectDT에서는 연결하기 전에 같은 Delegate를 제거하도록 정리했다.

if (SubmitButton)
{
    SubmitButton->OnClicked.RemoveDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );

    SubmitButton->OnClicked.AddDynamic(
        this,
        &UDailyProblemWidget::HandleSubmit
    );
}

NativeOnInitialized와 NativeConstruct

한 번만 준비할 작업은 NativeOnInitialized()가 더 어울릴 수 있다. 화면에 다시 들어올 때마다 갱신해야 하는 값은 NativeConstruct()나 별도의 Setup 함수에서 처리한다.

NativeOnInitialized: 객체 수명 동안 한 번
NativeConstruct: View에 붙을 때 다시 호출될 수 있음
NativeDestruct: View에서 떨어질 때 호출

위젯 풀링이나 재사용 구조에서는 객체 생성과 화면 표시를 같은 사건으로 보면 안 된다. 버튼 연결, 데이터 초기화, 화면 갱신을 각각 어느 시점에 해야 하는지 나누는 것이 중요하다.