API Design – Should Event Listeners Be Held in Weak References?

api-designevent

Usually event listeners shouldn't outlive object that registered them.

Does it mean that event listeners should be held by weak references by default (stored in weak collections by the object listeners are registered on)?

Are there valid cases when listener should outlive its creator?

Or maybe situation like that is a mistake and it shouldn't be allowed?

Best Answer

Why shouldn't event listeners outlive the object that registered them? It seems like you are assuming event listeners should registered by methods of controls(if we take the GUI example) - or more precisely, methods by objects of classes that inherit the GUI toolkit's controls. That's not a necessity - you could, for example, use a specialized object for registering event listeners and ditch that object afterwards.

Also, if event listeners were weakly referred, you would have to actually keep references to them even if you never use that reference. Failing to do so will make the listener be collected at a random time. So, we get a bug that is

  • Easy to create by mistake(all you have to do is to forget storing an object in a reference variable that you'll never use).
  • Hard to notice(you'll only get that bug if the GC collect that object).
  • Hard to debug(in the debug session - which always works like a release session - you'll only encounter that bug if the GC collected the object).

And if avoiding that bug is not good enough incentive, here are some more:

  1. You'll have to think of a name for each listener you create.

  2. Some languages use static anlysis that'll generate a warning if you have a private member field that's never get written or never get read. You'll have to use have a mechanism for overriding that.

  3. The event listener does something, and once the object that has it's strong reference is collected it'll stop doing that something. You now have something that affects the program's state and depends on the GC - which means the GC affects the concrete state of the program. And this is BAD!

  4. Handling weak references is slower, since you have another level of indirection and since you need to check if the reference was collected. This wouldn't be a problem if having event listeners in weak references was necessary - but it isn't!

Related Topic