Is it possible to free()/delete an object by calling the free() method on it's Reference?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By redsharktooth22

Hello everyone,
I’m trying to delete an object, that I only have a reference to. To be a bit more specific, I am calling free() from inside an object, that holds an array of the objects I’m trying to delete.
Here is what the code looks like (I don’t know what else to show).

agent_body.queue_free()

The error message is just tells me:

Attempted to free a reference.

Thus I’m not sure if I should just make a method like kill() in the object I’m trying to delete that just executes:

self.queue_free()

and then call:

agent_body.kill()

Alternatively I tried to figure out if it is possible to get the object instance itself from the Reference() object, but I couldn’t find anything relevant there.
So should I go for the kill() method approach, or is there something better that I don’t know about?

:bust_in_silhouette: Reply From: Zylann

Objects inheriting Reference must not be freed explicitely. They get destroyed only once nothing else references them. If you have an array of references, simply setting the item to null will free it, if it’s the only place it is referenced.

You say you want to use free() from inside the object itself, however I can only tell you this is a bad design. It can have really nasty consequences.

In order to use free(), your script must inherit Object (or a class based on Object which doesn’t inherit Reference). But be careful about this, because it destroys the object right now. Any piece of code following the line with free() may potentially crash the game, because the object will be gone.

The most common pattern where an object “kills itself” is in the case of nodes, using the queue_free() function.
Indeed, objects inheriting Node don’t inherit Reference. So they are not ref-counted, and freeing them immediately frees them. However, because doing this immediately can lead your code to step over itself and crash, queue_free() is preferred so that the actual destruction happens during idle time, when scripts are done running.

If your object is also referenced inside an array somewhere, you may want to emit a signal so that the holder of the array removes the object from it. Or better, delegate destruction to this holder, so you won’t need signaling.

Hi, thank you very much for this detailed answer. I’m sorry I didn’t respond earlier, I kind of ignored this issue during the last week as I was squashing a lot of bugs in my code.

I basically made the mistake of writing a bunch of classes, not being concerned about how they are going to be placed into the scene tree.
Long story short, I totally circumvented this issue by working directly with nodes instead of classes.
The holder now simply calls queue_free() on the Node once it has everything it needs from it.

Best of wishes, Paul

redsharktooth22 | 2020-03-29 17:48

1 Like