ActionScript Clean Up - actionscript-3

i want to deallocate a spriteClass from memory and remove it from the display list.
when the spriteClass is instantiated, it creates some of it's own sprites with new tweens and tween events and add them as children. i understand that the tween events must be removed in order for the spritClass to become available for garbage collection, and only afterwards should i remove and nullify the spriteClass, but should i also nullify and remove the spriteClass's sprite children and tweens as well, or does it not matter?
essentially i'd like to know if by writing
spriteClass.deallocate(); //removes it's tween event listeners;
removeChild(spriteClass);
spriteClass = null;
it automatically removes all of it's added children and new instantiations like tweens, sprites, rects, whatever, or am i responsible for removing them all along with event listeners from within my spriteClass.deallocate() function?

As far as I'm aware, any child sprites should not need to be nulled to trigger garbage collection as long as there aren't any references to them from elsewhere.
However, you would need to remove any listeners on the children assuming they are not weakly referenced (an optional argument to addEventListener).
Also for reference, you can check yourself if the garbage collector is doing its job with the Flash Builder Premium profiler (http://help.adobe.com/en_US/flashbuilder/using/WS6f97d7caa66ef6eb1e63e3d11b6c4d0d21-7e46.html)
P.S. You can use the Flash Builder IDE even if its a pure AS3 or Flash project.

Related

Deleting everything from the stage AS3

So, I am wanting to clear my whole stage. I already searched through the internet, and unfortunately nothing has worked for my situation.
Basically, what I am doing is a somewhat complex maze generator and before I create a new one, I want to get rid of everything I created prior to that. So far, I hear that the best way to remove movieclips from the stage is buy using:
while(numChildren > 0)
removeChildAt(0);
However this only works for the current movieclip I call it in, which doesn't include the maze I generated. I just want to get rid of absolutely everything.
Any ideas on how to do this?
You're thinking along the right lines, you can use numChildren and removeChildAt however you need to call them in the scope of the stage:
while(stage.numChildren > 0)
{
stage.removeChildAt(0);
}
To just remove it from the stage:
stage.removeChildren();
Just removing clips from stage isn't always equal of removing them from memory
removeChildren, removeChild or removeChildAt does not actually remove an Sprite or any other DisplayObject from memory, it only removes it from the displaylist. That means if you create 1000 sprites and add them to the stage (displaylist), and then use removeChildren they could still exist in memory (forever). Then you have a memory leak.
To remove it from memory, all objects with a relation to the displayObject should be set to null. This includes event listeners and relations from / to non-displaylist related objects.
If you want to be sure all related stuff should be gone, just null it and check these things:
Remove it from the displaylist using removeChild or removeChildAt or removeChildren. (note this can be done from the stage)
Remove all eventListeners that are attached to the clip, or use weak event listeners.
If you used a reference in an Array, Vector, Dictionary or any other object, remove it from the object, set it to null or splice it using Array.splice()
setTimeout/setInterval should be cleared
Set the object = null
You can profile the memory with Mr Doob stats or performance stats from the Temple Library. You should see a drop (garbage collection) after a while when removing all clips. After removing multiple times the memory indicator should not be higher.

ActionScript 3 Removing All RESIZE Event Listeners

I'm working on a Flash project which is separated into separate scenes.
In Scene 1 I have multiple MovieClips (which include event listeners for RESIZE (and others) inside them).
In Scene 2 I have a few common MovieClips and new ones (which also include event listeners for RESIZE (and others) inside them).
After clicking a button from Scene 1 to go to Scene 2, it's fine, except for if I resize the stage and then I get the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
I know it's related to the event listeners, but it would be unrealistic to remove them each individually as it's expected there will be many.
If I undertand your situation correctly, I think you will in the end need to remove each listener individually, or add the resize listener only once. Since you mentioned scenes, am I right to assume you are working on the timeline? I also am assuming the null object reference error comes from a scene that has been removed from the stage, making reference to a display object that is no more, a ref to the stage after the scene has been removed, or just calling a function (the resize handler) on an object that no longer exists.
Some way to deal with this are:
Add some checking in the listener handler functions
if (!this.stage) return
To avoid the errors, but will not help if the object the function is a method of has been removed.
To avoid needing remember to remove hundreds of listeners, create removeAllListeners and addCustomEventListener functions. Instead of the usual addEventListener, call you addCustomEventListener which in turn will call addEventListener. Have addCustomListener store the target, listener function and event string in a dictionary or array of objects. removeAllListeners can loop through the dictionary or array and remove all your listeners. It is a bit like setting up an event hub, but does not go quite that far.
Instead of adding the RESIZE event listener to each scene, add it only once. Then in the listener function call a function on whichever scene is the active scene or view.
This last one is the approach I have seen most often, and is the most bullet proof. It may be tricky to implement on the time line, I have always been a little hazy on timeline variable scope.
Yes, so far as I know there is no good automated way to do this, however it would be a good practice to create a registerAllListeners and a removeAllListeners methods that manually add and remove the appropriate listeners to your object.

Flash memory management and Actionscript

There was many discussions about this problem, but I want to pay attention on the situations that IMHO seems not so clear:
Yes the general rules are:
Remove chachedAsBitmap
Stop movieClip if playing
Remove events
Delete references
etc.
But let's look:
First Example:
I have nested sprite (ex: mainSprite), it contains other sprites with dynamic textFields in it (and are chached as bitmaps), just textFileds and MovieClips with event listeners on it (with weak reference).
When I need to remove this sprite I need first to remove all it's nested content via loops or just
removeChild(mainSprite);
mainSprite=null;
is just enough?
Second Example:
I have some sprite in which I'm loading bitmap and manipulating with bitmapData, later I'm just replacing content of this sprite with another bitmap, is allocated memory for older bitmap automatically erases and is overwritten or it still exists?
Third example:
I have some "graphics template" MovieClip (in library with Export for Actionscript property set on it) which I'm adding on the stage and filling with dynamic data (and adding event listeners), let's say that it's one scene of the app, on another scene I need same MovieClip with other dynamic data, but inbetween need to clear my stage (need something like transition animation which is also library MovieClip), what's the best way: to set this MovieClip visible property to false (while transition animation is plays) and then reuse it, or just remove it with removeChild and then add when add with addChild once more?
All I wrote is more about Air Mobile, cause in most cases for the desktop these situations aren't so problematic, but in case of mobile development they are.
You can visually monitor memory usage along with fps etc using this lib: http://code.google.com/p/flash-console/
hope that helps.
P.S. gc in flash is always a weird thing :)
First example: removing mainSprite from display list is enough if there are only weak listeners on its children.
Second example: I'd advice reusing the same object with visible = false. Recreating the same object is more resource expensive plus you get another instance of the same thing being in memory before it gets gc'ed.

Flash CS3 - start whole stage/movie clip from beginning

I have a flash CS project. I have one stage and some frames. How can I start all project from beginning using AS3? Or start all stage's content from beginning? Is any possibility to do it?
MovieClip has a function gotoAndPlay(frameNumber).
So, you need a movieclip which is added directly to stage and that holds all other movieclips.
Note, that frames counts from 1.
update:
That's what I would do:
Make a wrapper movieclip, export it for actionscript.
In my main (document) class I would make a variable i.e. world:MovieClip to hold the wrapper.
Then I could dynamically create and delete this movieclip, and then create it again.
As I said, if you are being careful with references, the garbage collector will keep the memory clean. Objects that do not have references, eventListeners and that are not in the display list, will be deleted on the next GC iteration.

AS3 quick and efficient way of removing children and listeners and discarding the parent

Is there a fast and efficient way of removing all children listeners etc from my app. If everything is contained in a display object on the stage called View? I have lots of dynamically called children and their listeners do not get removed when I remove the View they reside in.
public function _discard ():void
{
// Quick way to discard the view, remove children and listeners
removeChild(View);
View = null;
}
Is this a valid way of removing the parent and children?
If you use weakly referenced listeners then the listeners will not prevent the objects from being garbage collected when you nullify them.
useWeakReference is the 5th parameter in the addEventListener call.
AFAIK, there is no way to enumerate listeners in ActionScript. So you have to write cleanup code, removeEventListener calls symmetrical to addEventListener.
alxx is right. there is no easy trick to solve this problem. In order to avoid removing manually all children/listeners, I would create a helper method that receives a View and recursively removes all children and their respective listeners.