Question about TWeakObjectPtr, trying to understand a bit more about Unreal garbage collection / check if I’m not understanding something correctly.
I see a lot of examples in my project’s code like the following, contained in a member function of a UObject derived class:
SomeObject->GetThingAsync().Then([WeakThis = MakeWeakObjectPtr(this)](const SD::TExpected<TSomeResult>& Result)
{
TSomeResult Profile;
if (!WeakThis.IsValid())
{
return;
}
WeakThis->DoSomething();
...
}
Note that this code and the continuation/callback are all being executed on our game’s main/game thread.
The question is, is this code unsafe?
Option #1 Reasoning that it is unsafe: If you just call WeakThis.IsValid(), there is no guarantee that your object/pointer will remain valid for any length of time after that check. I think implicit in this is that garbage collection could happen on another thread interleaved with your code running on the game thread. So the object could get cleaned up out from under us.
Instead with a weak pointer, you need to call Pin() to get a hard refcount to the object (by constructing a TSharedObjectPtr) and then it is safe to use (while the TSharedObjectPtr object is still alive and holding the refcount). See also this doc: https://dev.epicgames.com/documentation/en-us/unreal-engine/weak-pointers-in-unreal-engine
// Acquire a Shared Pointer from the Weak Pointer and check that it references a valid object.
if (TSharedPtr<FMyObjectType> StrongThis= WeakThis.Pin())
{
// The Shared Pointer is valid only within this scope.
// The object has been verified to exist, and the Shared Pointer prevents its deletion.
StrongThis->SomeFunction();
}
Option #2 Reasoning that it is safe: We are guaranteed that any UE garbage collection step that could invalidate the object being pointed to by WeakPtr must happen on the main game thread, and so there is no problem as long as all this code is running on the main game thread.
[Attachment Removed]