0

我有一个加载 swf 的预加载器,该 swf 创建了一堆侦听器、对象和影片剪辑。我希望所有这些都被销毁并重新创建。

我的预加载器的简化版本:

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);

当我尝试删除它时,我会这样做:

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);
4

4 回答 4

2

在您加载的 SWF 中,您可以创建一个“destroy”方法,该方法将删除所有侦听器、销毁所有对象并重置所有数据。

您可以从父对象调用此方法(如果该方法是公共的),也可以destroy在从舞台中移除 SWF 时调用 (Event.REMOVED_FROM_STAGE)

于 2012-10-30T14:32:36.170 回答
0

您可以使用 js 重新加载 swf,这是执行此操作的简单方法。你可以检查这个答案

或者你必须在 swf 文件中做好对象和监听器管理和重置游戏。随着项目变得越来越大,这可能会很复杂。您需要删除所有引用和侦听器的发布方法。

于 2012-10-30T14:41:15.330 回答
0

首先,您应该使用 Loader 类加载您的 swf,如下所示:

 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();
    //......
    //.
    //.
于 2012-10-30T21:08:08.120 回答
0

我知道这是旧的,但我偶然发现它以供参考,并看到一些我认为应该提及的东西。

System.gc() - 虽然它是您可以访问的函数,但我所看到的一切都表明垃圾收集器不应该被您的代码调用,除非您使用了大量内存并立即需要它。垃圾收集器通常比您更清楚应该何时运行(在 AS3 中强制垃圾收集?)。它不仅会影响您的应用程序的性能,还会影响在该浏览器或容器中运行的所有 Flash 应用程序的性能。

还有很多人在努力有效地使用 unloadAndStop(),因为它在各种情况下似乎相当不可靠(使用 unloadAndStop() 方法卸载 swf,但视频声音仍然可以听到)。

为彻底起见,我强烈建议您先从加载的 flash 对象中删除所有其他语言,然后再删除 flash 对象本身,而不是指望容器会为您处理它。这就是为什么 Flash 一开始就以内存泄漏着称。

在加载的 swf 中,添加在卸载时触发的代码。一种方法是将其添加到 swf:

this.addEventListener(Event.REMOVED_FROM_STAGE, doUnload)

然后让 doUnload 函数执行以下操作:

使用 removeEventListener 有效地终止事件处理程序。您可以调用您创建的所有 addEventListener,也可以编写一个例程来遍历并通过遍历播放中的对象将它们全部删除。第一个选项更有效,因为它是独占的,但从理论上讲,第二个选项是您可以在应用程序之间记忆和复制的内容。

对变量使用 delete() 以使它们被垃圾收集器移除。注意:与许多语言不同,除非引用也被删除,否则引用的变量将不可删除。例如:

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.

关于使用 removeChildAt(0) 还是单独删除子对象是否是一个好主意仍然存在混淆。第一个的好处是非常简单和直接,但这也给它一个警告,即编码人员不能完全理解它,并且可能会丢失类似于 unloadAndStop() 的东西。不如使用 removeChild 遍历对象树并毫无疑问或不确定地明确消除事物。

设置好后,添加卸载flash对象的函数会触发它的自删除,所以loader会保持简单整洁,重新加载flash很干净。

于 2014-05-02T23:01:25.487 回答