Navigation: Appendix B: Dolphin Pattern Book > Object Lifetime Patterns >
Object Liberation Strategy
Some objects represent external resources. How can we ensure that these external resources are correctly reclaimed when the object is garbage collected.
By convention, Dolphin adopts a number of methods associated with the termination of objects:
The #basicFree method should free (de-allocate) external resources owned by the receiver. After this has occurred the receiver is left in an invalid state and, as such, it is assumed that #basicFree can only be called once. So #basicFree:
|•||frees external resources|
|•||may leave the receiver in an invalid state|
|•||can only be called once|
The #free method should free external resources (typically by sending #basicFree) and also nil the instance variables referencing those external resources. This will allow these objects to recreate their valid state (often using Lazy Initialization) from the information contained in the receiver. Because the appropriate instance variables are nilled, #free can be sent to an object more than once. So #free:
|•||generally calls #basicFree|
|•||nils resource variables|
|•||allows the receiver to recreate its valid state (often lazily)|
|•||can be called more than once|
Finalizable objects receive the #finalize message (only once) just before certain death. Objects can be marked as finalizable by sending them the #beFinalizable message. #finalize should generally call #basicFree since there is no need to call #free as the object is about to die anyway. Therefore #finalize:
|•||is received just before certain death|
|•||generally sends #basicFree|
|•||should only be sent by the finalization mechanism|
|•||is only sent once|
The intention of #release is that it should remove circular references and dependents from the receiver. This was a convention adopted by the early Smalltalk-80 systems where weak references were not available. Since it is not necessary to remove circular references which involve a weak reference, the introduction of Weak Collections has meant that #release is less useful in modern Smalltalk programming. So #release:
|•||removes circular references and dependents|
|•||is generally not that useful now that weak references are available|
GraphicsTool is an abstract class which defines behaviour common to GDI objects (pens, brushes etc).
"Answer the receiver's handle. If unrealized then attempt to realize it first."
ifTrue: [self realize].
"Realize (create) the external resource associated with the receiver,
but only if not already realized. Subclasses must implement #basicRealize"
"Private - Realize (create) the external resource associated with the receiver, sent
from the public method, #realize, if not already realized."
"Free external resources held by the receiver, and leave in a state such
that the receiver will be re-realized the next time it is accessed."
(self isRealized and: [self ownsHandle]) ifTrue: [
handle := nil]
"Private - Free up external resources held by the receiver."
GDILibrary default deleteObject: handle
"Private - The receiver is about to expire, so free any external resources. We use #free
rather than #basicFree just in case the receiver has been explicitly freed whilst it was
waiting in the finalize queue."
Brush is the GraphicsTool subclass which represents Win32 GDI brushes:
"Private - Create the external brush resource associated with the receiver."
ifTrue: [self ownedHandle: self createHandle]
"Private - Answer an external handle to a new brush as described by the logbrush structure."
^GDILibrary default createBrushIndirect: logbrush