|Topic was automatically imported from the old Question2Answer platform.
Godot.Object directly or indirectly implement
IDisposable. They also provide the
How are we meant work with these two different memory management designs? Are we meant to call both
Dispose() or just one of them from C#?
Node.QueueFree() methods are just the C# counterparts of their GDScript methods.
Dispose() is a pure C# method that you can implement and call when you consider. For every
Godot.Object you have in C#, Godot already has another native object linked, so your C# object is just a bridge between your C# code and the native Godot object (you can access to the IntPtr using the
Godot.Object.Dispose implementation just calls to another
Dispose(bool disposing) virtual method, so you can override it safely to dispose another objects if you need it. This virtual method calls to
godot_icall_Object_Disposed to free the memory of the native godot object.
If you never free the objects, Godot engine will try to free them for you when reference count is 0 in case of
Reference or when the game is shutdown in case of orphan Nodes or Objects, and the
Dispose method will be called (the
bool disposing parameter will be
false in case of shutdown). Also, the C# Garbage Collector could try to free it at some point in the future if it consider it. When the GC destroy the C# Object, the
Dispose() method will be called, so the Godot engine will be noticed, freeing the native Godot object.
It’s a good practice to override the
Dispose(bool disposing) method and put more code there to dispose resources: just don’t forget to call to
base.Disposing(disposing) inside, or the native godot object will not be freed. More information about the usage of the IDisposable pattern here: When and How to Use Dispose and Finalize in C# - DZone
So, different behaviours can be achieved:
If you call to the
Free() method, the object will be freed immediately in Godot. This is useful when you want to get rid of the object as soon as possible. Sometimes you can’t use if: for instance, you can not free an object when you are inside of the method called by a signal emitted of the same object. Then you have to use
QueueFree() instead, but this method is only available for
Godot.Node. An alternative way could be wrap the method in an async method and await for the next frame with
await sceneTree.ToSignal(sceneTree, "idle_frame");, and call to the
Free() method after it.
If you call to the
Dispose() method, you can be sure the C# resources will be freed immediately (I mean, the
Dispose(bool disposing) method will be called), but the Godot instance will not be freed immediately.