I have some questions about UPROPERTY

You should use UPROPERTY when hosting raw pointers to any other UObject (Actor/ActorComponent), so the garbage collector can see it.

This has two implications, 1) Garbage collector will null that pointer if the actor/object gets destroyed. Without it, the pointer will end up being garbage (pointing to memory that is not valid).
2) Stops the object being destroyed from the GC (UObject more than actors/actor components, will explain later).

So as you can read above, the UPROPERTY macro is crucial. Actors (and its owned components) are slightly different, but need to be addressed. Actors are held in a UPROPERTY array on the World Object, Actors will always get destroyed regardless if other objects are holding a raw UPROP pointer to it. This is cause the world sets the actor Pending Kill. The Actor will then set all its owned components pending kill.

The GC will clear up UObjects when no more “raw” pointers are holding it alive or its been marked pending kill.

So the take away here is, you should always use UPROPERTY above your Arrays or pointers. Keep a valid chain of reflection so the GC can transverse if you want the GC to know about those pointers (to clear them up (null them) ) or to keep that object alive (reference track).

If you want to just hold a pointer to something and don’t want to deal with GC/Reflection, then use TWeakObjectPtr. This will not affect the object’s lifetime at all and will return false from IsValid if pointer is null.

Hope this clears things up.

4 Likes