Game Develop

[UE5] 유효성 검사. 본문

UnrealEngine5/이것저것

[UE5] 유효성 검사.

MaxLevel 2023. 8. 4. 00:54

언리얼 유효성검사하다보면, 막 배우는 사람들입장에서는 헷갈리는 부분들이 있다.

뭔 로우포인터쓰면 nullptr이 대입안되서 위험하고.. UPROPERTY쓰면 어쩌고 저쩌고....

다른 기준으로 좀 이해하기 편하게 쓰자면, 어떠한 액터의 Destroy()를 호출했을때를 기준으로 생각하는것도 괜찮다.

 

일단 UPROPERTY()가 명시된 액터의 경우, Destroy를 호출한 다음 GC가 호출되기 이전, 이후는 다음과 같다.

이전 : 여전히 기존의 메모리를 가르킴.

이후 : 변수에 nullptr대입 

 

즉, 만약 Destroy 호출 후에 GC가 호출되기 이전에 그저 해당 유효성검사를 nullptr로 한다면 개발자가 의도하지않은 동작이 일어날 수 있다는 의미이다. 

어쨌든 Destroy를 호출했다는 것은 해당 호출 이후에 더이상 이 액터는 사용하지 않을것이고 해당 메모리에 접근하지 않을 거라는 것을 명시한것이기 때문에 이런 일이 발생해선 안된다.

 

언리얼에선 Destroy를 호출한다고 바로 메모리에서 삭제하는게 아니다. GC로 메모리를 관리하기때문에 GC가 발동되어야만 메모리에서 삭제되기 때문에, 일단 Destroy를 호출하면 '이것은 다음 GC때 삭제할거다...'라고 표시를 한다.

해당 상태를 PendingKill상태라고 하며, 유효성검사를 하기위해선 이 PendingKill상태까지 검사해야 제대로 된 검사이다.

 (Destroy 호출 이후 해당 액터를 절대 안쓴다는게 개발자의 의도라면)

 

일단 앞서 말했듯이 UPROPERTY로 강참조된 액터는 GC가 가동된 이후에 알아서 해당변수에 nullptr을 넣어준다.

그래서 PendingKill상태까지 검사를 해주는 IsValid같은걸로 유효성검사를 하면 괜찮다.

 

다만, 로우포인터는 참조그래프에서 추적이 안되기 때문에 로우포인터가 참조하는 액터가 Destroy 되더라도, 해당 로우포인터변수에는 nullptr이 대입되지 않는다. (GC가 호출되기 전이든 이후든)

그래서 TWeakObjectPtr사용을 권장하는 것이다. 해당 객체로 관리할 경우, Destroy호출이후에 바로 nullptr을 대입해주기 때문에 로우포인터를 쓰는것에 비해 더 안전하며, 약참조이기 때문에 참조그래프의 부담을 줄일 수 있다.

 

로우포인터를 사용해서 메모리에 접근하기 전에 무조건 IsValid를 전부 다 박아놓으면 로우포인터를 사용해도 괜찮을수도 있긴 하겠지만...