Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 新实例未重置其计时器和子对象_Actionscript 3_Flash_Oop_Instance_Main - Fatal编程技术网

Actionscript 3 新实例未重置其计时器和子对象

Actionscript 3 新实例未重置其计时器和子对象,actionscript-3,flash,oop,instance,main,Actionscript 3,Flash,Oop,Instance,Main,(我在AS3和Adobe AIR for iOS SDK中工作) 该程序有两个类:第一类是program.as,这是FLA文件链接的对象。在程序中。正如一样,有一个函数用于启动程序,另一个函数用于重新启动程序。第二个类是myMain.as类,它调用finishNow()功能来自程序。作为重新启动程序 它在第一次运行时运行良好。问题是,几乎在它重新启动时,它似乎一直在自己重新启动。它给出了相当多的参数Error:Error#2025:提供的DisplayObject必须是调用者的子对象。也有错误。

(我在AS3和Adobe AIR for iOS SDK中工作)

该程序有两个类:第一类是
program.as
,这是FLA文件链接的对象。在
程序中。正如
一样,有一个函数用于启动程序,另一个函数用于重新启动程序。第二个类是my
Main.as
类,它调用
finishNow()功能来自
程序。作为
重新启动程序

它在第一次运行时运行良好。问题是,几乎在它重新启动时,它似乎一直在自己重新启动。它给出了相当多的
参数Error:Error#2025:提供的DisplayObject必须是调用者的子对象。
也有错误。我还注意到一些功能,例如计时器,在程序重新启动时不会再次从0启动??我真的很困惑,因为逻辑似乎是正确的,但痕迹表明并非如此

将跟踪放在
程序中。如
显示
finishNow()函数在第一次运行后被重复调用。问题在于
programRestartTimer
没有在新实例上重置。通过调用
stop()programRestartTimer
上的code>function可暂时修复此问题。从不断显示的
错误#2025
中,我怀疑在第一次运行时未删除的显示子项(或类似的,例如其他计时器也未重置)导致了此问题。这意味着要么程序没有创建一个全新的实例,要么AS3不可能

Program.as:

package  {

    import flash.display.MovieClip;

    public class Program extends MovieClip {

        var runMain:Main;

        public function Program() {
            startNow();
        }

        function startNow() {
            runMain = new Main(this);
            addChild(runMain);
        }

        function finishNow() {
            removeChild(runMain);
            runMain = new Main(this);
            addChild(runMain);
        }
    }
}
Main.as:

package {

    import flash.display.Sprite;

    public class Main extends Sprite
    {
        public var program:Program;
        var programRestartTimer:Timer = new Timer(8 * 1000);

        public function Main(stageHolderTemp) {
            program = stageHolderTemp;
            trace(program);

            someFunctionsThatDrawGraphics();
            moreFunctions();
        }

        function callFinishFunction():void { // this is called at the end of the animation
            programRestartTimer.start();
            programRestartTimer.addEventListener(TimerEvent.TIMER, restartProgram);
        }

        function restartProgram(e:TimerEvent):void {
            programRestartTimer.stop(); // this line is a temporary "fix" to stop the program from constantly restarting
            // it doesn't actually fix the full problem
            program.finishNow();
        }

    }
}

在AS3中,当然可以设计一个类,以便能够重新初始化自己。但这需要仔细设计重启例程

首先,您的
callProgramRestart()
函数向程序实例添加了一个侦听器,但它从未被删除,这将导致您的程序在第二次调用后重置两次,这很可能是删除子错误的原因-您将连续删除它们两次。通过使用
flash.utils.setTimeout()
()并将其设置为调用
restartProgram
函数,可以完全消除对该侦听器的需求

function callFinishFunction():void { // this is called at the end of the animation
    flash.utils.setTimeout(restartProgram,8000);
}
function restartProgram():void {...}

其次,您应该在某个地方进行“完全”重新初始化。您创建
Main
类的另一个实例的方法很可能会起作用,但是在调用该类之前,您应该正确地清除前
Main
实例的侦听器。

您应该首先在
restartProgram()中删除计时器上的事件侦听器
并像这样实例化计时器:
var programRestartTimer:Timer=new Timer(8*1000,1)以便每个计时器仅调度一个计时器事件。那有用吗?谢谢,我来试试。我想我会坚持使用
TimerEvents
作为
setTimeout()
在AS3中似乎已被弃用,尽管它仍然有效。更不用说在整个程序中我有很多
TimerEvents
。关于“完全”重新初始化,这是否意味着我必须记住在添加后的某个时间点删除程序中的所有DisplayChild、TimerEvent侦听器、TouchEvent侦听器等?你能解释一下为什么我必须在创建新的
Main
实例之前清除以前的侦听器吗?-新的
Main
中的所有内容不应该都是全新的吗?如果你不删除所有的侦听器,你的旧
Main
对象或它的子对象,这取决于什么对象侦听事件,仍然会对某些事件做出反应,更不用说它不会被GC'd,因此最终您的应用程序将崩溃。在这种情况下,不需要删除子对象,因为如果父对象将停止从任何位置被引用,则其子对象也将得到GC'd。侦听器在垃圾收集方面被视为对对象的附加引用。您可以通过在侦听器中使用“弱”引用(参数
usewakreference
为true)来避免这种情况。当您说,“…旧的
Main
对象或其子对象(取决于对象侦听事件的内容)仍将对某些事件作出反应…”时,会有点混淆。在program.as中作为
finishNow()函数在添加新实例之前删除旧实例中的代码。或者事实并非如此(我的旧
Main
还在吗)?我的印象是,新实例只是访问旧的侦听器和计时器,因为它们没有被清除——因此需要完全重新初始化。我不认为我可以依赖GC,因为它们需要在重新启动时完全清除。虽然有事件侦听器连接到旧的
Main
实例,但它仍然在内存中“存在”,并且它可能会干扰新的
Main
实例,例如,如果它触发静态方法或任何SharedObject数据更改。不,除非由
程序提供,否则新的
Main
实例应该创建自己的
计时器
对象,并且应该使用自己的
TimerEvent.Timer
侦听器。罪魁祸首在这里,如果由旧的
Main
计时器或新的
Main
计时器发送,事件是相同的。好的,我想我现在明白了。因此,基本上我的理解是:最好的解决方案是记住手动删除
计时器
触摸
/
单击
中的事件侦听器?而显示子对象可以不删除吗?