In Theory

When a class object is removed from the stage, as in obj.removeChild(childObj), Flash keeps it active in memory, in case you add the same object again. Reactivating a removed object happens frequently and is good practice for controlling memory usage. Also, since class-based objects are always passed to methods by reference, you may be using the same object without knowing it at times (you shouldn’t not know it, but it can happen), and you may be using a deactivated object.

The problem is that event listeners are also still active, and running! And that is a problem because this is memory/processor time you don’t need to waste – Flash is already bulky enough. For example, if you are creating a child object every time a frame event occurs, those child objects are still being created.

The solution is simple: stop the listeners on deactivation. For all DisplayObject-based classes written, you should also write standard methods for adding/removing listeners: activate(e:Event) and deactivate(e:Event). In deactivate, listen for activation; similarly, in activation, listen for deactivation.

Though I came on these ideas semi-independently, there are some really good explanations and examples out there. This is good explanation:

http://wiki.mediaboxtraining.com/doku.php/flash:display_list_deactivation

Though I couldn’t immediately find it, I think Senocular has talked about it, and here is his stage activation detection kit:

http://www.senocular.com/flash/actionscript.php?file=ActionScript_3.0/com/senocular/events/StageDetection.as

In Practice

Here is a sample class setup with activation/deactivation detection. Please note that this is generic – that is, sometimes the activation listener should not be removed, or other listeners may require removal, but not activation (they are activated by some other method, by user interaaction, etc.).

import flash.display.MovieClip;
class TestClass extends MovieClip
{
public function TestClass()
{
this.addEventListener(Event.ADDED_TO_STAGE, activate, false, 0, true);
}

protected function activate(e:Event):void
{
if (e !== null) { e.target.removeEventListener(e.type, activate); }

// ADD all event listeners here. . .

this.addEventListener(Event.REMOVED_FROM_STAGE, deactivate, false, 0, true);
}

protected function deactivate(e:Event):void
{
if (e !== null) { e.target.removeEventListener(e.type, deactivate); }

// REMOVE all event listeners here. . .

this.addEventListener(Event.ADDED_TO_STAGE, activate, false, 0, true);
}
}

– 30 –

Advertisements