Asynchronous API:s and garbage collection

The asynchronous API:s in Flash, Flex and AIR don’t all work the same in regards to garbage collection. I discovered this the other day when testing out file uploading in Flash. I made the mistake of not keeping a reference to the object that was going to dispatch events when the user had selected a file. It took me half an hour to figure out what was happening, and once I did I cursed myself for not seeing it straight away. However, after having thought about it I think that the the Flash, Flex and AIR API:s are inconsistent and a bit unintuitve on this point.

What I did was this:

private function selectFiles( ) : void {
  var fileReference : FileReference = new FileReference();

fileReference.addEventListener(Event.SELECT, selectHandler); fileReference.browse(); }

private function selectHandler( event : Event ) : void { info.text = FileReference(event.target).name; }

The problem is that once selectFiles has run the fileReference is deallocated because it is local to the function and there are no references to it anywhere else. Once it has been deallocated there is nothing left to dispatch the event that will trigger the selectHandler method. For other, similar cases, the garbage collector may not deallocate the instance before it has time to dispatch an event simply because it didn’t run in the time between the object going out of scope and the dispatching of the event, but in this case there is user interaction involved, which takes time of another magnitude.

By coincidence Oliver Goldman (of Adobe) wrote about more or less the same problem around the same time as I scratched my head and wondered was going on.

If some one else made this mistake I would probably sneer, and call it a rookie mistake. However, after thinking about the problem, and reading Oliver’s post I have decided that it’s an easy mistake to make.

Why? Partly because, as Oliver points out, the Flash, Flex and AIR API:s have a couple of different classes you use in this way, and not all behave the same. Instances of some classes, for example URLStream (Flex), will not be garbage collected, but FileReference (Flash) and File (AIR) will.

The other reason is that it’s quite odd that a FileReference instance is deallocated after browse has been called and the open window is running. It’s true that the reference goes out of scope, but you would think that the runtime must keep a reference to the calling object, how else is it going to post back once the selection is done? Apparently it does this with a weak reference, or something to that effect.

Acording to Oliver, Adobe has decided on trying to simplify the API and make sure that at least the AIR API works like URLStream, that is, the runtime keeps a reference until the asynchronous request is finished. I think this is a good idea, as it makes no sense that the runtime should keep a reference as long as the request hasn’t returned anyway. It’s more intuitive.

Just for the record, I chose to have the fileReference variable local to the function because I wasn’t interested in keeping it. The reasons are too uninteresting to include here, it suffices to say that I was only testing how much information about the file you could get hold of before it was uploaded.

One Response to “Asynchronous API:s and garbage collection”

  1. JabbyPanda Says:

    I had highly enjoyed your analysis, keep up sharing your gained knowledge while developing for Flash platform with a rest of the fellow developers :)

Leave a Reply