Actionscript 3 新实例未重置其计时器和子对象
(我在AS3和Adobe AIR for iOS SDK中工作) 该程序有两个类:第一类是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必须是调用者的子对象。也有错误。
program.as
,这是FLA文件链接的对象。在程序中。正如
一样,有一个函数用于启动程序,另一个函数用于重新启动程序。第二个类是myMain.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
计时器发送,事件是相同的。好的,我想我现在明白了。因此,基本上我的理解是:最好的解决方案是记住手动删除计时器
或触摸
/单击主
中的事件侦听器?而显示子对象可以不删除吗?