2012-06-26 105 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。 –