Preventing UTexture2d from GC'ing without UProperty()?


I need to know how to prevent a UTexture2D from beeing garbage collected without referencing it inside a UObject with the UProperty() macro.
Because in Slate I have an SImage and it’s given FSlateBrush has to be able to swap out it’s rendering resource. But obviously it gets gc’ed if I only set it with the SetRenderingResource() method…

FSlateBrush has an member method “AddReferencedObjects”, and that needs an FReferenceCollector, but I have no Idea how to use that class, if that’s even the correct way to prevent it.

Any Advice? :slight_smile:

PS. First I’ve tried a TSharedPtr, but it doesn’t seem to work with an UTexture2D (or UObject derived classes)
And I doubt .AddToRoot() is correct/intented way either, even if it works.

AddToRoot is the proper way to prevent GC if you don’t have a UObject to hold on to the reference. “Something” has to hold on to that reference (which is what UPROPERTY does), so adding it to the Root does just that. Just make sure you call RemoveFromRoot when you want it to get cleaned up.

@ExtraLifeMatt Thanks for the answer, but the thing is, it could be possible, that the same Texture2D is used by different Slate Widgets, so if I call RemoveFromRoot() after it got changed in one SImage/ Slate Widget while beeing in use in another, the second one is going to be gc’ed, is there no manual referencing possible with UObjects? :frowning: (something like TSharedPtr etc.)

Nope. Not to my knowledge. The UPROPERTY is the “ref counting” in that it just cares if ANYTHING has a reference to it and doesn’t actually track how many things are referencing it. You could write a simple wrapper that does your own ref counting.

Okay, guess I’ll have to do that.
Thanks for the info!

If someone might have the same problem in the future, my working solution for that is:

I’ve added a

mutable TSet<UObject*> GCPrevent;

to the corresponding FSlateWidgetStyle (e.g. in a GlobalStyle or if needed in a lifetime restricted Style for specific gamemodes). Cause It’s a USTRUCT() it can contain UPROPERTY()'s, unlike Slate classes.


It seems to me the correct way is to use the FSlateDynamicImageBrush with new/delete operators. :slight_smile: