0

I have a preloader that loads a swf, the swf creates a bunch of listeners, objects, and movie clips. I want all of these to be destroyed and recreated.

Simplified version of my preloader:

var request:URLRequest = new URLRequest("myfile.swf");
var myLoader:Loader = new Loader();
var urlLoader:URLLoader = new URLLoader();


urlLoader.addEventListener(Event.COMPLETE, function(event){ 
    stage.addChild(myLoader);
    myLoader.loadBytes(urlLoader.data);
});

urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(request);

When I try to remove it, I do this:

stage.removeChild(myLoader);
var child = loader.myLoader.content as Object;
SoundMixer.stopAll();
while(stage.numChildren > 0){
     stage.removeChildAt(0);
}
child.stop();
while(stage.numChildren > 0){
     stage.removeChildAt(0);
}
child=null;

System.gc();
myLoader.unloadAndStop(true);
System.gc();
myLoader.unload();
System.gc();
myLoader.loadBytes(urlLoader.data);
stage.addChild(loader.myLoader);
QuinnBaetz
  • 559
  • 9
  • 23

4 Answers4

2

In your loaded SWF you may create a method 'destroy' which would remove all listeners, destroy all objects and reset all data.

You can call this method either from the parent object (if the method is public) or you can call destroy when you remove the SWF from stage (Event.REMOVED_FROM_STAGE)

strah
  • 6,702
  • 4
  • 33
  • 45
0

You can reload swf with js, this is the easy way to do this. you can check this answer.

Or you have to do a good object and listener managment and reset game in swf file. This might be complex as project get bigger. You need release methods that removes all references and listener.

Community
  • 1
  • 1
ymutlu
  • 6,585
  • 4
  • 35
  • 47
0

first you should load your swf using the Loader Class like this :

 var movie:MovieClip
        var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
        loader.load( new URLRequest("myfile.swf"));

        function loadComplete(event:Event):void
       {
        movie = loader.content as MovieCLip;
        addChild(movie);
       }


    //when reloading just remove the movie object from the stage

     removeChild(movie);
    SoundMixer.stopAll();
    //......
    //.
    //.
Khaled Garbaya
  • 1,479
  • 16
  • 20
0

I know this is old, but I stumbled on it for reference and see some things that I think should be mentioned.

System.gc() - while it's a function you have access to, everything I've seen suggests that the garbage collector should never be called by your code unless you've used a considerable amount of memory and need it back immediately. The garbage collector usually has a better idea of when it should run than you do (Force Garbage Collection in AS3?). It can impact performance for not just your application but all flash applications running in that browser or container.

There's also a good bit of people struggling to make effective use of unloadAndStop(), as it seems to be rather unreliable in various contexts (Unloading swf using the unloadAndStop() method, but video sounds remain audible).

To be thorough, I'd strongly suggest putting the effort into simply eliminating everything as it would be in any other language from within the loaded flash object first before removing the flash object itself, not expecting the container to take care of it for you. This is why Flash has a reputation for memory leaks to begin with.

Inside the loaded swf, add code that fires on unload. One way is to add this to the swf:

this.addEventListener(Event.REMOVED_FROM_STAGE, doUnload)

Then have the doUnload functon perform the following:

Use removeEventListener to effectively terminate the event handlers. You could either recall all the addEventListeners you created, or cook up a routine to walk through and remove them all by traversing the objects in play. The first option is more efficient since it's exclusive, but the second option would theoretically be something you could memorize and copy between applications.

Use delete() on variables to make them removable by the garbage collector. NOTE: Unlike many languages, a referenced variable will not be removable unless the reference is also removed. For example:

var a:int = 0;
var b:int = a;

delete(a); // b still exists and equals 0, a is not available to GC.
delete(b); // now both variables can be removed by GC.

There's also still confusion as to whether it's a good idea to use removeChildAt(0) or remove the child objects individually. The first has the benefit of being distinctly simple and straight-forward, but that also gives it the caveat of not being entirely understood by the coder, and possibly missing something similarly to unloadAndStop(). Not as much as walking your object tree with removeChild and eliminating things explicitly without question or uncertainty.

After this is set, adding a function to unload the flash object will trigger its self-removal, so the loader will remain simple and neat, and reload the flash cleanly.

Community
  • 1
  • 1
Weaselgrease
  • 13
  • 1
  • 4