You might have heard about weak references which are used when listener functions for events in Action Script are being set. In 2006 gskinner was wondering why all the listeners were not set in weak reference mode. Some of guys on Habrahabr in comments to my article about functions contexts insisted on the fact that weak references are the bad practice and all the operations related to their removal you should do only manually.
I have known about them for a long time because I try to keep tabs on all Adobe’s news but I understood how it works recently just after using Flex Builder’s profiler. Instead of retelling background information I will give you an example where you might see how useful these weak references may be:
public class GuestbookEntry
{
public function get comments() : ArrayCollection
{
return _comments;
}
public function set comments(value : ArrayCollection) : void
{
if (_comments != null)
{
_comments.removeEventListener(CollectionEvent.COLLECTION_CHANGE,
onCommentsChange);
}
_comments = value;
if (value != null)
{
value.addEventListener(CollectionEvent.COLLECTION_CHANGE,
onCommentsChange, false, 0, true);
}
}
protected function onCommentsChange(event : CollectionEvent) : void
{
switch (event.kind)
{
case CollectionEventKind.ADD :
CommentEntry(event.items[0]).guestbookEntry = this;
break;
}
}
private var _comments : ArrayCollection;
}
Let’s imagine we have got a guest-book and its record type GuestbookEntry which is represented above. This type has its own collection of comments. Let the comment be described by CommentEntry type. Somewhere there is an UI form for adding new comments. By the architecture of the project we are required to give each comment a reference to guest-book’s record by guestbookEntry property.
GuestbookEntry instances are likely to be received from server but it doesn’t matter. In comments property’s setter I subscribe to the collection change event to control the moment of adding a new comment. As you can see the reference to the method onCommentsChange is transfered into the collection as weak one (the last argument of addEventListener method).
During application profiling with such a kind of code before using weak references in it all of instances of the GuestbookEntry that have ever been created remain there. The inspector of loitering objects shows two types of connection between GuestbookEntry and CommentEntry instances: one is maintained via guestbookEntry property another one via onCommentsChange (its instance is held by the collection of comments) method’s savedThis (the context of the function) which refers on the guest-book’s entry.
As far as I understand Flash Player’s garbage collector automatically clear the memory from objects that are connected with the help of strong references (including cycling ones) but if there are event references it can’t do anything. That is where weak references may be useful. There is no risk of using them because usually they are the last references that are left between objects and are ready to be collected.
Thoughtful reader who loves Martin Fauler will mention and ask what stop us from deleting these references manually? I will answer: nothing, but such decisions would be bulky and ugly. In this case I might need to realize something like dispose() in GuestbookEntry class:
public function dispose() : void
{
comments = null;
}
and call this method everywhere where I say goodbye to the instances of entries in the guest-book. It is boring, old-fashion and not practical at all.
UPD.: After discussing with colleagues I found out some situations where weak references may play a dirty trick on you. For example if you have an object without strong references which is linked to another object by weak reference it would receive events until it is deleted by garbage collector and probably the processing of these events may appear to be unexpected as far as you have forgot about that object. To avoid such situations you of course need to delete listeners manually.
My example does not have that kind of issue. As guest-book entries are deleted along with their comments it is impossible to change the collection of comments after straight references to GuestbookEntry are removed and before they are deleted by garbage collector.