2013-03-18 14 views
0

(我正在AS3和Adobe AIR for iOS SDK中工作)。新實例不重置其定時器和孩子

該程序有兩個類:第一個是Program.as這是什麼FLA文件鏈接到。在Program.as有一個功能啓動程序和另一個重新啓動程序。第二類是我的Main.as類,它調用Program.asfinishNow();函數重新啓動程序。

它在第一次運行時運行良好。問題是,幾乎只要它重新啓動,它似乎保持自己重新啓動。它也提供了很多ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.錯誤。我也注意到,當程序重新啓動時,諸如TIMERS之類的一些函數不會再從0開始?我真的很難過,因爲邏輯似乎沒問題,但痕跡說不然。

將跡線放入Program.as表示finishNow();函數在第一次運行後被重複調用。問題在於programRestartTimer未在新實例上重置。通過調用programRestartTimer上的stop();函數暫時修復此問題。從持續顯示的Error #2025中,我懷疑在第一次運行中顯示未被刪除的Childs(或類似的 - 如其他定時器也未重置)導致此問題。這表明,或者程序不是創建一個全新的實例,或者它不可能用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(); 
     } 

    } 
} 
+0

你應該先在'restartProgram()'中刪除你的定時器事件監聽器,並像下面這樣實例化你的定時器:'var programRestartTimer:Timer = new Timer(8 * 1000,1);'這樣每個定時器只會發送一個計時器事件。這有幫助嗎? – duTr 2013-03-18 02:51:26

回答

0

這肯定是在AS3可以設計一個類,以便它能夠重新初始化。但是這需要仔細設計重啓例程。

首先,您的callProgramRestart()函數爲程序實例添加了一個偵聽器,但它永遠不會被刪除,這會導致程序在第二次調用後重置兩次,這很可能是您刪除子錯誤的原因 - 您連續兩次去除它們。通過利用flash.utils.setTimeout()the manual)並將其定位爲調用restartProgram函數,可以完全消除該聽衆的需求。

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

其次,您應該在某處執行「完全」重新初始化。您創建Main類的另一個實例的方法應該很有用,但在調用此方法之前,您應該先清除聽衆以前的Main實例。

+0

謝謝,我會試試這個。我想我會堅持使用'TimerEvents'作爲'setTimeout();'在AS3中似乎不推薦使用,即使它仍然有效。並不是說我在整個程序中都有很多'TimerEvents'。關於「完全」重新初始化,這是否意味着我將不得不記住在添加之後,在程序中的某個時刻總是刪除所有的displayChilds,TimerEvent監聽器,TouchEvent監聽器等等?你能解釋爲什麼我必須在創建一個新的'Main'實例之前清除以前的監聽器嗎? - 新的'Main'中的所有內容都不是全新的? – ArrayOutOfBounds 2013-03-18 14:35:13

+0

好吧,如果你沒有刪除所有的監聽器,你的舊的'Main'對象或它的子對象(取決於什麼對象監聽事件),仍然會對某些事件作出反應,更不用說它不會被GC'd了,因此最終你的應用程序將崩潰。在這種情況下,刪除子對象不是必需的,就好像您的父對象將停止從任何地方引用一樣,其子對象也將獲得GC'd。在垃圾收集方面,監聽器被視爲對象的附加引用。您可以通過在監聽器中使用「弱」引用(參數'useWeakReference'爲true)來避免這種情況。 – Vesper 2013-03-19 03:48:59

+0

當你說,'...你的舊'Main'對象或它的子對象時,根據對象監聽事件,仍然會對特定事件做出反應......',這有點令人困惑。在program.as中,'finishNow();'函數在添加新實例之前刪除舊實例。或者事實並非如此(我的舊'Main'還在那裏)?我的印象是新實例只是訪問舊的監聽器和定時器,因爲它們沒有被清除 - 因此需要完全重新初始化。我不認爲我可以依靠GC,因爲他們需要在重新啓動時清除。 – ArrayOutOfBounds 2013-03-21 16:33:41