Best Practices for ActionScript Event Listeners

I see a lot of incorrect instantiation of event listeners, and I’ve also done it wrong quite a few times myself, especially when coding really fast. Doing it right is easy and the following four steps could save you a ton of debugging time later. 

Step 1: First, create the object. In this case I’m creating a Timer object using the ActionScript flash.utils.Timer Class:  

var myTimer:Timer = new Timer(1000);

Step 2: Second, always add your event listeners before executing any of the objects methods. And always, always attach the event listener to an object. Simply calling an addEventListener without attaching it to an object means the listener will receive any events broadcast for that type of event. This can become a nightmare in projects that may have dozens or even hundreds of event listeners running and you have to debug a problem. 

//myTimer is the object to which we will attach the listener.
//timer is the type of listener we want to observe.
//And, timerHandler the function to call when the event occurs.
myTimer.addEventListener(“timer”,timerHandler);

Step 3: Third, now you can call the objects method. I’m going to call the start() method which will kick off the Timer: 

myTimer.start();

Step 4: Lastly, when you are done with an object, always remove the event listener. Leaving event listeners active when they aren’t needed can cause memory leaks. If an object is not removed, it is still registered and it will remain in memory. By removing the event listener, you’ll allow the garbage collector to eventually deallocate it from memory. 

    myTimer.removeEventListener(“timer”,timerHandler);

Why do things in this order? If you add your event listeners after calling a method, such as start(), you can potentially miss an event that occurs right before the event listener is created. By only calling methods after event listeners are created you eliminate the possibility of missing something and banging your head against the wall while trying to debug it under a heavy deadline. 

Here’s a complete Flex 4 sample app that you can play with to try it out: 

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx">
 <fx:Script>
     <![CDATA[   

       private var myTimer:Timer;

       public function timerHandler(event:TimerEvent):void
       {
          var date:Date = new Date();
          textArea1.text = date.hours.toString()+
             ":"+date.minutes.toString()+
             ":"+date.seconds.toString()+
             ":"+date.milliseconds.toString();
       }   

       protected function start_clickHandler(event:MouseEvent):void
       {
           myTimer = new Timer(1000);
           myTimer.addEventListener("timer", timerHandler);
           myTimer.start();
       }

       protected function stop_clickHandler(event:MouseEvent):void
       {
           myTimer.stop(); 
           myTimer.removeEventListener("timer", timerHandler);
       }
  ]]>
 </fx:Script>

 <s:TextArea id="textArea1" x="15" y="70" width="270" height="20"/>
 <s:Button x="15" y="28" label="Start" click="start_clickHandler(event)"/>
 <s:Button x="103" y="28" label="Stop" click="stop_clickHandler(event)"/>
</s:Application>