MultiCast Events: auto-remove-on-free for non-components?
When a listener object, that registered his method in the event, is destroyed, it is neat if the de-registration was done automatically.
This is implemented now when the listener object is derived from TComponent.
However sometimes TComponent is not wanted for being too heavy or for any other reason.
It would be nice if Spring.Event offered another method for non-component auto-deregistration. Of course it would still require some plumbing, but the boiler plate can be made very small.
See the neat implementation of pluggable auto-remove at
Comments (3)
-
repo owner -
reporter Thanks. I would review it when have more time. It is not a trivial matter.
Preliminary reply would be two points.
1) sure, any framework might be abused. Especially one, trying to bring safe language features into a cpu-native language. Misusing this event can "cause AV in smoe situations", which however does not mean it is too dangerous to be used. It is aways a tradeoff.
2) The linked sequence of articles and the code to mee seem sophisticated enough to make sudden destruction nearly impossible given proper use of the solution linked. Yes, misuse IS possible, yet Jolyon's scaffolding seems ot make "safe" use straightforward and easy.
3) with your implementation i worry about inherited call in .Notify - it looks like if we would have a TComponent with the .OnDestroy: IMulticastNotifyEvent - then the component destruction callbacks would be hooked twice... Probably not big deal, as the first call would remove the second call, but still looks shady...
I guess, to make this design flexible, hooking should be moved into an explicit pluggable scaffolding, so if one method did register the hook, others would not.
3.1) cnRemove doesn ot test for OnDestroy becoming nil, which is unusual but possible :-) :-P
-
repo owner - changed status to wontfix
1) It's not about abusing. The point is that the solution with the interface might break code that hooks up events while holding the object reference that not yet has been assigned to an interface and I am not risking that.
2) The implementation you linked in fact has possible issues with destruction on both side of the event.
3) You can still exit after the inherited if Item.Data is a TComponent or not run the inherited but instead use the other way.
3.1) I ignored that possibility on purpose.
- Log in to comment
The interface is no option because this might cause object destruction in certain situations. Also any option will always cause some additional overhead no matter how it will be implemented.
But thanks to the flexible design of the events you can write your own one that does this - here is an example (I did not test it through completely):