AS3 - how to remove children/subchildren and all associated event listeners from memory


#1

I have a complex as3 application that builds many composite moveiclip objects inside one another. I want a mechanism that will allow me to delete the highest level movie clip (the parent of all the others inside) that will also remove all the children from the display list and from memory and all their associated event listeners.

it’s easy to remove the children from the display list by just looping on numChildren and using removeChild. but that doesn’t remove the display objects from memory nor does it remove their event listeners.

Anyone with any ideas?

Thanks,

Mark.


#2

Instead of manually removing the events, you can mark them as having a weak reference. Weak reference listeners does not count on the garbage collection process. Do this in right in the addEventListener function:

object.addEventListener(eventType, function, bubbles, priority, useWeakReference);

Set it as true and the weak reference will not count towards as reference when doing garbage collecion.


#3

you can test if they have listeners using object.hasEventListener(type)

In FP10 you can use stopAndUnload() but I think this is only for externally loaded content… not sure …

you could weakly reference your event listeners on the objects too then its likely the garbage collection may take them out of memory…?


#4

As far as I understand it (and i may be wrong) - useWeakReference set to true will still not garbage collect until the objectt the event is set on is set to null. Since some of my objects are 10-15 levels deep in other movieclips I would fid it difficult o do this. I wanted to be able to get rid of the owning parent movieclip remove all decendants from the diplay list, remove the object and remove their event listeners.

The only other way I can think of doing it is manually by writing a “killme” function for every one of my class/functions but this is rather onerous.

Any other ideas?

Thanks, Mark.


#5

Have you taken a look at “Grant Skinner’s Janitor class”:http://www.gskinner.com ?

You can download it here: “Janitor class”:http://www.google.com/url?sa=t&source=web&ct=res&cd=3&url=http%3A%2F%2Fsvn.riaforge.org%2Fflexshell%2Ftrunk%2Fflexshell_extern%2Fsrc%2Fcom%2Fgskinner%2Futils%2FJanitor.as&ei=6Pj9SYe3Fp7qsgPu1MTJAQ&usg=AFQjCNFHh6pXVwWKoZhzwlq5Q2yg2aYdaA

If you’re using a loader, you should remove listeners and any other references, then use the unload() method.

“Unload method reference”:http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Loader.html#unload()


#6

It’s not always possible …

http://www.gskinner.com/blog/archives/2008/04/failure_to_unlo.html

*Flash Player 9 Bug*
Flash Player 9 has a critical bug that prevents unloading loaded SWFs that have any active ENTER_FRAME or TIMER event listeners. This occurs regardless of whether these listeners are all within the scope of the loaded SWF, or even if they all use weak references. This also affect timeline code written in Flash authoring - *if you have any code in your timeline, it will not be possible to unload that SWF.*

#7

Yes unfortunately a killMe type function is necessary. You can register everything with Skinner’s Janitor class and then add a REMOVED_FROM_STAGE listener and then call the Janitor inside it’s function. This way you can run your loop and when the object is removed from the stage the Janitor will take care of the rest.


#8
The only other way I can think of doing it is manually by writing a "killme" function for every one of my class/functions but this is rather onerous.

This is personally what I do with every piece of loaded content, I also have addListeners() and removeListener() functions.

If there is another way then i’m all ears :slight_smile:


#9

This is an excellent discussion. I am having issues with implementing nested timeline references hanging about and throwing NULL errors in the parent when the swf is deleted.

I don’t have a solution. My development relies heavily upon this kind of architecture.
I’m not seeing solutions here as yet but will update when i have sported this out.
Cheers oyster


#10

Ok here’s my fix for my issues commented above.

When the nested swf is deleted.
Code on it’s timeline has a listener for a child clip on the timeline.
In this case “bear_mc”

stage.addEventListener(Event.ENTER_FRAME, moveBg, false, 0, true ); stage.addEventListener(Event.ENTER_FRAME, moveTracker, false, 0, true); bear_mc.addEventListener(Event.REMOVED_FROM_STAGE, deleteG);

All the listeners with the original top two causing the errors

then

function deleteG(evt:Event):void {
stage.removeEventListener(Event.ENTER_FRAME, moveBg);
stage.removeEventListener(Event.ENTER_FRAME, moveTracker);

}

This fixed my errors of NULL references being thrown in the parent.

Hope this helps