flash display_list_deleting_objects

Deletion of display objects

To delete a DisplayObject we call the removeChild method on its container, a DisplayObjectContainer. The removeChild method takes the DisplayObject parameter to delete from the display list and to send its reference:

public function removeChild(child:DisplayObject):DisplayObject

It is essential to remember that the deletion of a graphic object is always done by the parent object. The removeChild method is therefore always called on the container object:

myContainer.removeChild ( child );

Due to this, a graphic object is not capable of deleting itself as it could with the existing removeMovieClip method in ActionScript 1 and 2

It is however capable of asking its parent to delete it:

parent.removeChild ( this );

It is important to remember that the calling of the removeChild method proceeds with a simple deletion of the DisplayObject within the display list but doesn’t destroy it.

An old reflex linked to ActionScript 1 and 2 could make you think that the removeChild method is equivalent to the removeMovieClip method. This is not the case.

To see this behavior, open a new Flash CS3 document and create a clip type symbol. Place an instance of it on the main timeline and call it myCircle.

On an AS layer we add a call to the removeChild method to delete the clip from the display list.

removeChild ( myCircle );

We could also think that the myCircle clip had also been deleted from the memory. But if we add the following line:

removeChild ( myCircle );
// display : [object MovieClip]
trace( myCircle );

We see that the myCircle clip still exists and has not been deleted from the memory. In reality we have deleted our myCircle clip from our display. This is no longer rendered but continues to exist in the memory.

If a developer doesn’t take this into account the application performance can be put into jeopardy.

Take the following case: an Event.EVENT_FRAME is listened to by an instance of the MovieClip:

var myClip:MovieClip = new MovieClip();
myClip.addEventListener( Event.ENTER_FRAME, listener );
addChild ( myClip );
function listener ( pEvt:Event ):void
{
trace("execution");
}

In deleting the instance of MovieClip from the display list with the help of the removeChild method, we note that the event is still broadcast:

var myClip:MovieClip = new MovieClip();
myClip.addEventListener( Event.ENTER_FRAME, listener );
addChild ( myClip );
function listener ( pEvt:Event ):void
{
trace("execution");
}
removeChild ( myClip );

To free up more memory a DisplayObject deleted from the display list we have to make its references null and wait for the garbage collector. Remember that it deletes objects that no longer have any reference in the application.

The following code deletes our clip from the display list and changes its reference to null. This is therefore no longer referenced in the application rendering it eligible for the garbage collector:

var myClip:MovieClip = new MovieClip();
myClip.addEventListener( Event.ENTER_FRAME, listener );
addChild ( myClip );
function listener ( pEvt:Event ):void
{
trace("execution");
}
removeChild ( myClip );
myClip = null;
// display : null
trace( myClip );

As we have deleted all the references to our MovieClip this is not deleted from the memory immediately.

During our development, we can however manually trigger the garbage collector in the debugging player with the help of the gc method of the System class.

Remember that the passing of the garbage collector is differed! We cannot know when it will intervene. The player manages it in an autonomous manner depending upon the system resources.

It is therefore imperative to foresee a deactivation mechanism for the graphic objects in order for them to use the minimum of resources when they are no longer displayed and waiting to be deleted by the garbage collector.

In the following code, we trigger the garbage collector with a mouse click on the stage:

var myClip:MovieClip = new MovieClip();
myClip.addEventListener( Event.ENTER_FRAME, listener );
addChild ( myClip );
function listener ( pEvt:Event ):void
{
trace("execution");
}
removeChild ( myClip );
myClip = null;
stage.addEventListener ( MouseEvent.CLICK, clickMouse );
function clickMouse ( pEvt:MouseEvent ):void
{
// garbage collector triggered
System.gc();
}

By clicking on the stage, the Event.ENTER_FRAME event stops being broadcast because the passing of the garbage collector has had a definitive deletion of the MovieClip.

We will come back to this point in the article entitled Deactivation of graphic objects.

Imagine the following case: we need to delete a group of clips that we have just added to the display list.

Open a new Flash CS3 document and place it multiple instances of the MovieClip symbol on the main stage. It is not necessary to give them instance names.

In ActionScript 1 and 2, we have many possibilities. A first technique consists of storing the references to added clips in an array, then browsing them to call the removeMovieClip method on each reference.

Another method is to browse the continer clip with the help of a for in loop to get each property which refers to clips to be able to target and then delete them.

When you want to delete a graphic object positioned in a specific index we can use the removeChildAt method. Here is its signature:

public function removeChildAt(index:int):DisplayObject

In discovering this method we can be tempted to write the following code:

var lng:int = numChildren;
for ( var i:int = 0; i< lng; i++ )
{
removeChildAt ( i );
}

On execution the previous code generates the following code:

RangeError: Error #2006: The indicated index is not within the limits.

A RangeError error type is raised because the index that we have passed to the getChildIndex method is considered as out of bounds. This error is raised when the passed index doesn’t correspond to any child contained by the DisplayObjectContainer. Our code cannot function as we haven’t taken into account a very important behavior to ActionScript 3 called depth collapse.

Worth remembering

  • Each DisplayObjectContainer contains an internal array containing a reference to each child object.
  • All manipulation methods of display objects work with the internal array of child objects in a transparent way.
  • The depth is generated automatically.
  • The quickest method to access a child object is getChildAt.
  • The addChild method doesn’t need a depth and stacks each child object.
  • The removeChild method seletes a DisplayObject of the display list but doesn’t destroy it.
  • To delete a DisplayObject from the memory we need to make its references null.
  • The garbage collector will intervene when it wishes and will delete any objects not referenced in the memory.







Adobe Training center


Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42