Class GameDev* SheepAdult

[Unreal Engine 5] Dangling Delegate 본문

Unreal Engine

[Unreal Engine 5] Dangling Delegate

SheepAdult 2023. 7. 24. 02:13

개인 프로젝트를 진행 중에 Dangling Delegate 문제로 인해 많은 시간을 소비했다. 인벤토리 구현 중, 인벤토리 위젯 내의 다른 위젯 클래스의 함수가 캐릭터 컴포넌트에 선언된 업데이트 관련 delegate에 바인딩 되어 있었다. 인벤토리를 온오프하면 인벤토리 위젯은 당연히 삭제 되므로, delegate에 바인딩 된 함수도 같이 해제해 줘야 하지만, 이를 처리하지 못한 문제였다. 문제는 이상하게도 해당 함수가 바인딩 된 것 처럼 실행은 된다는 것...(인벤 토리의 구조체들은 업데이트가 되지만 widget은 업데이트 되지 않았다.)

 이전엔 코드가 아래와 같았다.

/* 인벤토리 슬롯들을 나열하는 그리드 클래스 */  
// InventoryGrid.cpp
void UInventoryGrid::UpdateInventoryGrid()
{
    ...
    if (!InventoryComponent->OnInventoryUpdate.IsBound())
    {
        // 만약 이미 바인딩되어 있다면 바인딩을 진행하지 않는다.
        InventoryComponent->OnInventoryUpdate.AddUFunction(this, FName("UpdatedInventory"));
    }
    ...
}

위에서 보면 맨 처음 인벤토리를 열었을 때 위의 InventoryGrid 위젯이 생성된다. 이 때 해당 함수가 delegate에 바인딩되며, 만약 이 위젯이 제거된다면 바인딩 된 함수를 dangling delegate가 될 것이다. 이는 예상치 못한 일을 야기할 수 있으므로 아래와 같이 수정했다.

void UInventoryGrid::NativeDestruct()
{
	// 소멸자에서 바인딩 함수 제거
	InventoryComponent->OnInventoryUpdate.Clear();
    Super::NativeDestruct();
}

void UInventoryGrid::UpdateInventoryGrid()
{
	...
	InventoryComponent->OnInventoryUpdate.AddUFunction(this, FName("UpdatedInventory"));
    ...
}

이로써 Dangling Delegate 문제를 해결할 수 있었다.