Destruction of object in Pharo/Smalltalk - When I clean resources?
I have a complexe object with many internally events references. I want know what is the best place where I have put the code for clean that resources when the object is cleaned for Garbage collector. I have fear that references never out, and still throwing notifiers.
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
(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
self normalHandlingOf: ann]
(4) This is what ephemerons will help for, it will allow us to write
anAnnouncer weak on: Announcement do: [:ann | myInstvar := ann foo + ann
and still have them cleaned by finalization.