2012-06-26 59 views
0

一般的看法是當你從舞臺上移除一個組件時,你還需要手動移除所有的孩子,這樣他們就不會在內存中浮動。因爲父容器已被移除,所以它們不可見。移除元素/子元素是否也移除作爲皮膚一部分創建的元素?

舉例來說,這將是BorderContainer中的Label組件。我的理解是你需要先刪除Label然後再刪除BorderContainer

當您創建組件(如TitleWindow)時,它的默認外觀將closeButton添加到標題欄/標題。

我添加了一個事件監聽器到關閉按鈕。 TitleWindow.closeButton.addEventListener();在關閉按鈕事件調用的函數中,我想關閉/刪除窗口。

我的問題是這樣的。我是否需要手動刪除closeButton作爲TitleWindow的子項?或者我只是刪除聽衆,然後從舞臺上刪除TitleWindow和皮膚創建的組件自動刪除/垃圾收集?

+0

下面的答案解釋了從顯示樹中爲通用情況(不包括下面的皮膚信息)中刪除父項意味着所有子項都不再與所有連接/使用的對象的圖形關聯(它將是一個孤立的圖)這意味着他們有資格收藏。如果存在任何邊緣/引用(事件監聽器或簡單對象引用)將其綁定到活動對象的圖形上,則不會收集它(因爲它可能稍後被訪問,這可能導致空對象引用)。 – shaunhusain

回答

2

如果組件從舞臺上移除,只要您刪除了al事件監聽器,它的所有子組件都將自動被刪除並進行垃圾收集。所以你不需要明確地去除孩子,以便他們被垃圾收集。

但是在你的問題中,你指的是皮膚。使用皮膚時,其主機組件的skinDestructionPolicy屬性始終設置爲never(除一個移動類外,我忘記了哪一個)。這意味着皮膚及其所有孩子將永遠留在記憶中,永遠不會收集垃圾。

現在不太開心的部分:覆蓋此默認設置並不容易。閱讀這個問題和我在那裏寫的答案,看看它是如何完成的:Spark SkinnableComponent skinDestructionPolicy

請注意,在99%的情況下,這種默認行爲並不是問題。當然,我不知道你的具體情況,所以我不能就此進行評論。

+0

我想澄清,正如你所說皮膚保留。這是否意味着該皮膚的一個副本被所有使用該皮膚的組件持有和共享?或者是否有每個組件的皮膚實例?如果我添加一個面板,刪除它,添加另一個面板,這是否意味着我在內存中有兩個皮膚?或者第二個面板是否使用第一個面板中的內存中的皮膚? –

+0

@phil_whiteboy這裏沒有任何對象池:每個外觀都是一個新的實例。這是有道理的:假設你會通過CSS樣式來改變一個實例;如果所有皮膚都是相同的實例,則該風格將應用於使用該皮膚的所有組件,這不是您想要的。 – RIAstar

1

我學到的傳統智慧與你的不同。當你從舞臺上移除某些東西時;根據定義,所有的孩子都不在舞臺上。假設沒有對主要組件或子項的引用,它們都應該有資格進行垃圾回收。

現在,如果您將一個事件偵聽器添加到TitleWindow的關閉按鈕;無論是否從舞臺中刪除TitleWindow都會釋放垃圾收集的組件,取決於誰擁有偵聽器。

如果TitleWindow包含偵聽器,那麼由於TitleWindow不再處於舞臺上,它和它的所有子項都應該有資格進行垃圾收集。

如果主應用程序或任何仍在舞臺上的組件持有事件偵聽器,那麼您必須在該組件或它的子組件之前刪除該事件偵聽器纔有資格進行垃圾回收。

+0

我也不是肯定的,但是從我讀過的所有內容來看,如果一個偵聽器沒有被手動刪除,它和它所連接的對象將留在內存中。除了將weak設置爲true時,默認爲false。 –