-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signal trying to access freed listeners C# #74984
Comments
I don't know about godot specifically, but in C#, += a listener to a delegate requires that you unsubscribe with -= if the producer will outlive the consumer. Can you not add a -= to the disposable of the instance? I would put a print statement in your callback when you do the .connect() method to verify if it's hitting BOTH instances, I'm suspicious that that reference in connect() pins the instance and keeps it alive even though it's not being actively processed. If this is the case you'd get the print twice. Do let me know as I currently am thinking this is expected due to how C# delegates work, and that your connect() version is actually leaking memory. I've seen many an application leak memory due to delegates pinning objects. |
Interesting. Although I use C# professionally, I use GDScript in Godot. I'd be interested in how Godot even knows how to unsubscribe events like that given even standard C# apps don't support this, and will absolutely cause a memory leak. |
i faced the same problem, my solution was to is i manualy unsubscribed the event in tree exisiting event. |
IMO the documentation should be changed to match what @fahadTheTechIdea said. Even if it did work properly in Godot, it's an anti-pattern and makes no sense in the .net world. |
When are you calling that method? |
i'm calling on the tree_exiting() event for the scene ( Scene is "OptionMenuControl") } |
Thank you. Now just to confirm, is there something wrong with doing it this way:
Or with overriding of the
Still, the documentation about this is a bit confusing. |
Duplicate of #70414 |
Godot version
4.0.stable.mono
System information
macOS 13.2.1 - Apple M1 (2020)
Issue description
I have an auto-loaded scene (single node) with a script that contains a signal, and a public method that is used to emit the signal:
[Signal] public delegate void ExperienceCollectedEventHandler(float amount); public void EmitExperienceCollected(float amount){ EmitSignal(SignalName.ExperienceVialCollected, amount); }
When the main screen loads, the listeners are appended using the
+=
operator (which the documentation suggests):GameEvents gameEvents = GetNode<GameEvents>("/root/GameEvents"); gameEvents += OnExperienceCollected;
Everything works fine until I relaod the main scene.
After the original listeners of the mentioned signal are freed, every time the signal is emitted, it's trying to access the disposed objects and call methods on them.
The solution I found is, instead of using the C# syntax to add a listener (
+=
), to use aGodotObject.Connect(...)
. This way, after the nodes are freed, the signal isn't trying to reach them anymore.Steps to reproduce
autoloaded.signal += listenerMethod
).ReloadCurrentScene()
orChangeSceneToFile(...)
Minimal reproduction project
If the project is needed let me know.
The text was updated successfully, but these errors were encountered: