Does an EventDispatcher have subscribed listeners ?
Lately I’ve been reading several discussions around the internals of EventListener, how easy is to create memory leaks, the dependencies between IEventListener and EventListener and onther fancy things. Robert Penner has lots of details around these topics in his 2 part articles:
Even though not a solution I want to add a new parameter to this equation that might help (at least for debugging purposes).
As per the documentaqtion flash.sampler.getMemberNames returns an object containing all members of a specified object, including private members. If we pass a reference to an EventDispatcher instance we will get a private member called listeners. Yes, you’re right, it’s the list of listeners the EventDispatcher has associated.
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.sampler.getMemberNames;
public class testEvents extends Sprite {
public function testEvents() {
var myDispatcher:EventDispatcher = new EventDispatcher();
myDispatcher.addEventListener("myEvent1", handler1);
myDispatcher.addEventListener("myEvent2", handler2);
var members:Object = getMemberNames(myDispatcher);
for each (var name:QName in members) {
if (name.localName == "listeners") {
trace(myDispatcher[name].length);
myDispatcher.removeEventListener("myEvent1", myDispatcher[name][0]);
myDispatcher.removeEventListener("myEvent2", myDispatcher[name][0]);
trace(myDispatcher[name].length);
}
}
}
private function handler1(event:Event):void {
trace("handler1");
}
private function handler2(event:Event):void {
trace("handler2");
}
}
}
The example above shows how we can get a reference to the different listeners declared in an EventDispatcher and how to remove them without having a direct reference (and knowing the event name arggg).
Even though this can help you to figure out if an EventDispatcher has listeners or not there’re still several problems you might find:
- You don’t have any information about the listener
- You don’t know which event the listener is listening to
- We don’t know which phase the listener is listening to
- Haven’t done too much testing around this, but I think both weak and strong references are hold in the list
- The other thing to consider is that flash.sampler.getMemberNames only works in the debugger version of the Flash Player
A very uggly implementation for a removeAllListeners method could be something like:
for each eventName that the dispatcher can dispatch
eventDispatcher.removeListener( eventName, listener ) for all phases
If after each removeListener we check the length of the listeners list we could find out the events the listeners were listening to as well as the phase and thean provide some debugging information around it.
5 Comments to “Does an EventDispatcher have subscribed listeners ?”
Leave a Reply

This is amazing! Thanks for discovering this; it gives me ideas.
I’ve wondered several times how this could be accomplished…
Thanks for sharing Xavi!!
Never checked the profiling APIs before.
Very interesting indeed
In some memory leak hunting scenarios I’ve found useful monkeypatching FlexSprite and overriding addEventListener to keep a list of listeners as described in dough McCune’s post: http://dougmccune.com/blog/2008/02/21/monkey-patching-flexsprite-to-list-all-event-listeners-on-any-flex-component/
It’s the hackish way to accomplish the same…
I’ll definitely give it a try when I have some time.
Thanx for sharing!
cheers
That code does not work. Calling getMemberNames on an EventDispatcher returns null, even the the “instanceNames” parameter set to true. Attempting to access the private “listeners” property of an EventDispatcher, which shows up in the debugger, generates a runtime error, which is the standard behavior in ActionScript 3. Obviously, none of the previous posters have actually tried this, nor has the poster of the code.
nice one – however, the API documentation states “For Flash Player debugger version only”, so it won’t be of any use when the code runs in a release version Player.
Dirk.