views:

3343

answers:

2

I have an array of FileReference objects which have several listeners attached to each of them, should I be removing each listener in it's handler method, or should I remove them all in the complete handler?

I read somewhere to use weak references for listeners, but I would think it would be better to explicitly remove listeners (yes?/no?)

for each(var f:Object in fileCollection){
   var myFile:FileReference = f.file; 
   myFile.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData)
   myFile.addEventListener(ProgressEvent.PROGRESS, onProgress);
   myFile.addEventListener(IOErrorEvent.IO_ERROR, onError);
   myFile.addEventListener(Event.COMPLETE, onComplete);
 }

 private function onUploadCompleteData(e:DataEvent):void{
   // doin my thing here
   removeListeners(e)
 }

 private function removeListeners(e:Event):void{
   var myFile:FileReference = FileReference(e.target)
   myFile.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData)
   myFile.removeEventListener(ProgressEvent.PROGRESS, onProgress);
   myFile.removeEventListener(IOErrorEvent.IO_ERROR, onError);
   myFile.removeEventListener(Event.COMPLETE, onComplete);
 }
+5  A: 

It's always a good idea to remove your listeners explicitly when you no longer need them, yeah, and the way you're doing it is fine. It might seem a little verbose, but it's still good practice, and it keeps you in the habit of knowing where your listeners are, since not knowing leads so often to leaks and unexpected behavior.

As for useWeakReference, I almost always use it myself, in addition to removing unneeded listeners. For me, it's become the rule rather than the exception. If you had to choose one, though, remove your listeners explicitly. Personally, though, I do both.

In fact, the I've found the number of occasions in which it'd be best to leave useWeakReference false, since doing so will prevent objects from being garbage collected, is especially rare. Indeed, before I learned what that argument was for (blog post here), I spent a ton of time scratching my head after getting runtime exceptions stemming from the Flex framework making calls on components I was sure I'd removed from the display list.

Deepa Subramaniam mentioned it obliquely in her component-model talk at last year's MAX conference (an excellent talk well worth checking out); I believe the way she put it was something like, "I don't know why the Flash player team chose to make false the default rather than true, but 99% of the time, you're going to want to set that value to true."

Christian Nunciato
Your blog post was helpful, checked out the MAX talk too, thanks.
Ronn
+1  A: 

If you're adding objects to a DisplayObject, I would recommend removing listeners when the Event.REMOVED_FROM_STAGE event is fired, and adding them when it is added to stage. This is an easy way to make sure listeners are removed with explicitly having to call the removeListeners function you wrote. For example, in your code segment, if the load fails then the listeners will never be removed.

iworkinprogress