Does calling Destroy() on a GameObject/MonoBehavior drop references to any event listeners?

I know that source objects (defined as the object who owns the event) will keep a reference to anyone who is listening to it’s events, so it’s important to make sure the listeners unsubscribe lest you cause a memory leak.

I’m now wondering the reverse - if I call Destroy() on GameObject SourceObject with MonoBehavior SourceScript on it, will that drop references to anyone who is listening to SourceScript’s events?

Or, do I have to make sure that all the listeners unsubscribe themselves from SourceScript’s events before it gets destroyed?

Yes they are dropped as long as all references to the source script instance are gone. Keep always in mind that inside the managed world it’s not possible to destroy any object. When you call Destroy on a gameobject / Monobehaviour you only destroy the native C++ counterpart. The managed part of the object will remain as long as there is a reference to it somewhere inside the managed world.

If you have a reference to your sourceScript in a thrid script like that:

public MySourceScript script;

and you destroy that instance by calling Destroy on the script or the containing gameobject the source script native part will be destroyed and the managed part will be marked as destroyed but still remains in memory until all references to it are gone so it can be garbage collected.

The script variable above will appear to be null after you call Destroy, but it actually isn’t. Unity fakes that the reference is null when the object has been destroyed.

So the actual managed part of the instance will still remain and if it has an event with other subbed objects they will remain as well until the reference to the dead source script instance is gone, In that case the GC will clean up all left over objects.

The check

if (script == null)
    script = null;

seems silly but actually has a use in Unity. It removes the fake null reference and allows the GC to collect the managed object.

Of course when you set a new instance to the variable the old reference will be gone as well.