On 08.10.2011 11:36, nullPointer wrote:
How to deal with it differs:
- Do you need strong guarantees that the "gone" object does not receive
announcements after your last reference to it is gone?
If no, don't use action blocks(1), and rely on the weak cleanup that the
event systems do (2).
If yes, is there a point where you can umbiquously determine whether the
last reference is gone?
If yes, either unsubscribe from source at this point, or prepare
the object for unsubscription(3).
If no, it's probably best to change your code. I can't think of a
way to do it in a couple of minutes, and suspect whatever solution one
might come up with will be intricate and hard to understand.
(1) The block itself will usually contain a strong reference to the
receiver and thus finalization will never kick in.
So you will have to clean it manually if using blocks(4)
(2) Events (notified with #triggerEvent:, registered with
#when:send:to:) are weak by default.
Announcements are strong by default, you make weak subscriptions by
(fast) sending #weak to the announcer before registering:
anAnnouncer weak on: Announcement send: #handleThis: to: self
or (compatible) makeWeak to the AnnouncementSubscription returned by
#on:send:to:
(anAnnouncer on: Announcement send: #handleThis: to: self) makeWeak
(3) With announcements you don't need a strong reference to the
announcer, just a way to check whether it's valid.
Then, in your action, you can do:
anAnnouncer on: Announcement
do: [:ann : announcer |
self shouldReceive ifFalse: [^announcer
unsubscribe: self].
self normalHandlingOf: ann]
(4) This is what ephemerons will help for, it will allow us to write
handlers like:
anAnnouncer weak on: Announcement do: [:ann | myInstvar := ann foo + ann
bar]
and still have them cleaned by finalization.
Cheers,
Henry