2012-01-25 85 views
0

我正在使用ActionScript 3(即,我們使用的Flex很少)編寫的Flex/Air應用程序(使用PureMVC)。視圖組件添加到主應用程序窗口中的畫布對象,然後這些視圖加載其他影片剪輯,圖像文件等。銷燬從舞臺上刪除的對象(及其子)

當我從舞臺上刪除視圖時,我使用application.canvas.removeChild(...)來執行此操作。這會在該視圖的PureMVC調解器中觸發一個事件,該事件將刪除設置的所有事件偵聽器,並且所有事件看起來都是花花公子。

但是,影片剪輯仍在後臺播放。他們沒有在屏幕上造成任何麻煩......但他們只是在那裏,在內存中播放某處(例如,我可以看到他們的trace聲明),我希望他們離開。我懷疑從畫布中刪除的視圖仍然存在,但我無法證明它。

將視圖設置爲null不會執行任何操作。我很驚訝AS3不包含任何簡單而有效地銷燬顯示對象及其所有子項的方法。

是否只有這樣才能沉悶地卸載所有的影片剪輯等,然後希望Flash能夠清理它們?

回答

2

AS3是垃圾收集語言,因此沒有明確的命令從內存中刪除對象。但是,AS3 VM確實會執行引用計數,所以如果您從階段中刪除顯示對象並刪除對該對象的所有引用,則該對象將立即或很快之後被銷燬,因此您將不再看到來自它等等。

如果您已經刪除了所有對該對象的明顯引用,但它沒有被收集,則問題可能是循環引用。例如,父對象和子對象互相引用,因此上述處理將不知道要除去它們,除非您將所有內容解除。在這些情況下,直到垃圾收集(即標記掃描)發生時,對象纔會從內存中移除。 (GCS相對較慢因此播放器內部優化時它們發生基於多少內存可用以及其他因素。)

順便提及,以上所有是所有對象的真實的,而不管它們是否是顯示對象或Flex視圖或NetStreams或其他。欲瞭解更多信息,AS3 GC的here's a good overview - 這是舊的,但仍然是正確的。

但是,作爲一名程序員,你應該瞭解的是,在幾乎所有情況下,你都不必擔心這一點。刪除所有對象的引用(如果他們正在播放,則爲stop()),並讓(經過嚴格優化的)內部GC確定它們何時實際消失。如果內存不足,那麼GC將起作用,如果不存在,那麼任何額外的內存管理都只是過早的優化。

+0

我打算髮表我自己的回答,但我最終會說大部分是同樣的事情(+1),但我要補充的一件事是eventListeners是保持實例活動的時間比應該長的一個大罪魁禍首。如果您不能明確地分離處理程序,那麼添加處理程序作爲[弱引用](http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/events/EventDispatcher.html#addEventListener())可以提供幫助處理程序。 –

+0

也使用適當的分析器,就像Flash Builder Pro中的分析器一樣,這是一種更好的方式來獲得有關內存使用和GC行爲的一些硬編碼。 –

+0

是的,弱處理程序是一個好主意,我希望它們是默認的。如果在這種情況下框架正在處理它們,那麼它們可能不是問題,但仍然是好的。 – fenomas

0

這裏有

  1. 兩件事情,如果你想刪除你的應用程序動態生成的,然後一個簡單的removeChild之或removeChildAt將有效地從舞臺中刪除影片剪輯。將變量設置爲null實際上是。
  2. 如果影片剪輯是外部加載的swf'與音頻/視頻數據,那麼你將不得不卸載所有這些以正確的順序。停止 - >卸載 - >從階段中刪除加載器 - >銷燬變量(根據需要)。

根據Flash播放器的版本,您有各種unloadAndStop類型的soundmixer類的方法和方法stopAll。

只有當您退出整個應用程序時,清理纔會進入畫面。

+1

有兩件事:首先,垃圾收集器動態清理對象,而不是退出時。其次,GC問題通常適用於外部加載的剪輯。即使'Loader.unloadAndStop()'也不會從內存中獲取剪輯,如果GC看到仍然有引用。 – fenomas

+0

同意,我相信我沒有說任何與此相矛盾的東西。刪除引用是它的一個模糊的簡短版本,我剛剛說明了它的實現的一些實例。無法刪除引用將不會刪除不需要的對象,直到退出。 –