Concerning removing event handlers, etc?

rickcr's Avatar

rickcr

20 Mar, 2010 01:41 PM

I'm pretty new to Flex/AS and was reading a chapter in Essential Action Script and it mentions you should always remove event listeners when they are no longer needed. I know this question isn't exactly RL specific but since I'm using RL I'm wondering if there are some framework things I need to consider. Iin my existing code and potential things to consider...

In one of my mediators I'm dynamically creating some components based off the class names I get back in some xml from a service call:

 //in setUpDataSelector function in mediator:
 for each(var pxml:XML in prompts) {
   var pmt:Prompt = UiHelper.instantiateUsingClassName( [email blocked]());
   //add Prompt component to layout
   dsLayout.dataselectorContainer.addChild(pmt as DisplayObject);
 }

The above can get called numerous times depending on what is clicked on from another menu. Before I'm doing the above, I'm making sure I remove any instances that were previously added to the container with:

 for each (var prompt:Prompt in dsLayout.dataselectorContainer.getChildren()) {
    prompt.removeEventListeners();
    prompt = null;
 }

Each Prompt component is supposed to implement removeEventListeners and manually remove any event listeners that were setup in Prompt.

Some questions:
1) Is it really necessary to remove event listeners even if you are removing the object from the display and setting it to null (Actually I was INCREDIBLY surprised that just setting it to null wasn't enough? You'd think setting an instance to null would at least make it eligible for garbage collection? Once set to null why wouldn't any event handlers registered also go out of scope and be removed?

2) Do I need to worry about my mediators that are bound to the prompt views that I dynamically create? Right now I'm doing nothing with them and I'm worried about memory issues. When I'm going through removing the prompts from the display and setting them to null, does the mediator instance backing that view eventually get cleaned up? What about event handlers in those mediators?

3) Related to 2, if I DO need to do something about the mediator that was backing a view that is no longer needed, How would I even know how to get a handle to them? I can know what components (prompts) were added and keep track of them, but I wouldn't necessarily know the mediator instances that were tied to those views (unless within each onregister of the mediator, I add 'this' to some global collection and then when I'm doing my remove of no longer needed components, I also then iterate over my global list of mediators and try setting them to null?

4) It's possible the user will again need the same prompts displayed (and obviously the same backing mediators will need to be registered), so if I do something like described in 3 - trying to set each mediator to null - would it be recreated again when I dynamically make a new instance of the prompt as initially shown?

Hopefully I'm just over-thinking all of this and I don't have to worry about the above too much?

Thanks for any clarifications.

  1. 1 Posted by rickcr on 20 Mar, 2010 06:35 PM

    rickcr's Avatar

    Ok, I should have looked more closely to the forum discussion since this link here described a lot of what I need to know:

    http://knowledge.robotlegs.org/discussions/questions/84-killing-views

    I do have a question though... in the example from the link above it mentions doing the following in a 'remove' method on the view which can be called from its mediator:

    if ( parent.contains(this) ) parent.removeChild(this);
    

    On a Flex forum I heard that just removing a component from the display isn't enough and you have to remove it and set it to null as well? Is this not true?

    But now here is my quandary..

    • If I iterate over my views and call remove() on them which in turn removes them from the parent component (and sets the component to null), how could I then remove any listeners I added to the view from the mediator in the mediator preRemove method, since I just set the view to null? Am I able to do the latter since as soon as I do parent.removeChild(), that will trigger the view's mediator 'preRemove' so that I could then remove any events I manually attached to the view in the mediator? I'm still fuzzy on the best practice here.

    Basically I have some event listeners add to view components directly in the mediator and some added to components directly within my mxml view as well. What's the order in how I should clean this up when I need to remove the view from its parent container?

    Thanks again.

  2. Support Staff 2 Posted by Joel Hooks on 20 Mar, 2010 06:44 PM

    Joel Hooks's Avatar

    I like to add a dispose method on my views (I implement an interface IDisposable) which does any cleanup that needs to happen. Typically this means nulling references, cleaning up binding, calling dispose() on children, and removing any listeners. With this approach your mediator simply needs to call view.dispose()...

  3. 3 Posted by rickcr on 20 Mar, 2010 07:52 PM

    rickcr's Avatar

    I'm curious, what about just doing all that in the mediator's remove or preRemove? This way you can also remove any listeners you manually added to view components directly from your onRegister in the mediator? Sometimes I'm attaching listeners to the view directly within the mediator so I need to remove them as well there. (At least I 'think' I do.. the whole issue of GC and event listeners is still vague in my mind.)

  4. Stray closed this discussion on 11 Feb, 2011 11:34 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac