안선생의 개발 블로그

[UE5] TWeakObjetPtr 본문

언리얼

[UE5] TWeakObjetPtr

안선생 2023. 11. 27. 13:26

TWeakObjetPtr는 참조 받을 때 사용합니다.

공식문서를 보면

 UProperty 가 아닌 오브젝트 포인터가 필요한 경우, TWeakObjectPtr 사용을 고려해 보세요. 이는 약 포인터로, 가비지 컬렉션을 방지하지는 않지만, 접근 전 질의를 통해 유효성 검사가 가능하며, 거기서 가리키는 오브젝트가 소멸된 경우 null 설정도 가능합니다.

즉 우리는 UPROPERTY매크로를 통해 가비지 컬렉션을 방지할 수 있습니다. UPROPERTY매크로가 루트셋에 참조하기 때문 하지만 우리가 UPROPERTY매크로를 사용하지 않고 오브젝트를 얻고 싶으면 rowPoint대신 TWeakObjectPtr을 사용해야 합니다.

아래 예제보겠습니다.

//..h

	class ATestActor* RowTestActor;

	UPROPERTY()
	class ATestActor* UPROPERTYTestActor;

	TWeakObjectPtr<ATestActor> TWeakObjectTestActor;


}

//. cpp
void ATistoryCharacter::BeginPlay()
{
	FActorSpawnParameters Params;
	UPROPERTYTestActor = GetWorld()->SpawnActor<ATestActor>(Params);
	RowTestActor = UPROPERTYTestActor;
	TWeakObjectTestActor = UPROPERTYTestActor;

	if (TWeakObjectTestActor.IsValid())
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor data : %d"), TWeakObjectTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor is nullptr"));
	}

	if (RowTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor data : %d"), RowTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor  is nullptr"));
	}

	if (UPROPERTYTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor data : %d"), UPROPERTYTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor  is nullptr"));
	}

	UPROPERTYTestActor->Destroy();
	GEngine->ForceGarbageCollection(true);

	if (TWeakObjectTestActor.IsValid())
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor data : %d"), TWeakObjectTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor is nullptr"));
	}

	if (RowTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor data : %d"), RowTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor  is nullptr"));
	}

	if (UPROPERTYTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor data : %d"), UPROPERTYTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor  is nullptr"));
	}

}

../TIck
void ATistoryCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);



	if (TWeakObjectTestActor.IsValid())
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor data : %d"), TWeakObjectTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("TWeakObjectTestActor is nullptr"));
	}

	if (RowTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor data : %d"), RowTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("RowTestActor  is nullptr"));
	}

	if (UPROPERTYTestActor != nullptr)
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor data : %d"), UPROPERTYTestActor->Data);
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("UPROPERTYTestActor  is nullptr"));
	}

}

 

1. 위에 간단합니다.액터를 스폰하고 Row포인터와 Weak포인터를 스폰한 액터를 참조합니다.  그후 데이터 값을 출력합니다.

 

2. 참조한 액터 Destroy하고 GC를 강제로 실행시킵니다.

 

3. Tick함수를 계속 확인합니다.

 

실행결과

1. Beginplay처음에는 모든 포인터에 데이터가 있는것을 알 수 있음

2. Destroy , GC강제 실행후 TWeakObjetPtr은 데이터가 없는것을 알 수 있음

3. Tick함수 실행시 가비지컬렉션으로 인한 UPROPERTY()매크로 포인터와 Weak포인터는 메모리가 해제 됐지만 Row포인터는 아직도 가리키는것을 알 수 있음(댕글링 포인터)

 

디버그

 

RowPointer

TWeakObjectPtr

UPROPERTY

 

RowPointer만 주소값을 가지고 있음 하지만 참조 대상 메모리는 해제되있는것을 볼 수 있다.

 

IsValid로 검사한 결과

 

IsValid는 객체가 존재하는지 확인 삭제된걸 바로 알 수 있음 Destroy를 확일할거면 IsValid를 쓰자

 

다른 포인터가 TWeakObjectPtr를 참조할라 할 때

에러가 뜸

 

요약 

1. Object를 참조할 때는 TWeakObjectPtr을 쓰거나 UPROPRETY를 쓰자

2. TWeakObjectPtr는 가비지컬렉션을 방지하는게 아닌 참조대상이 유휴한지 확인 할 수 있음

3. UPROPERTY매크로는 포인터를 소멸시키는  경우 자동으로  nullptr 이 됨

4. RowPoint는 GC로 인해 메모리는 해제되지만 댕글링 포인터(Dangling pointer)을 이르킴

5. IsValid로 객체는 존재하지 않지만 Row포인터는 무언가를 가르키고있음 

5. 객체가 파괴된지 확인할라면 IsValid를 쓰자.

6. TWeakObjectPtr를 다른 포인터가 참조 할 수 없다.

 

 

아래 사이트 참조 했습니다.

https://chogyujin-study.tistory.com/72

 

언리얼 엔진의 가비지 컬렉션

오늘은 언리얼 엔진의 가비지 컬렉션에 대해 공부하겠습니다. 1. 가비지 컬렉션? 가비지 컬렉션이란 메모리를 관리해주는 시스템으로 C#, JAVA 등 언어에는 기본적으로 가지고 있는 시스템입니다.

chogyujin-study.tistory.com

 

'언리얼' 카테고리의 다른 글

[UE5] 언리얼 가비지 컬렉션  (0) 2023.12.09
[UE5] 언리얼 스마트 포인터  (0) 2023.12.03
[UE5] 애니메이션 블루프린트  (0) 2023.11.13
[UE5] Cast  (0) 2023.11.11
[UE5] 액터 스폰하기  (0) 2023.11.06