我很难理解我期望成为内存管理的基本原则。希望有人可以提供一些解释,帮助我更好地理解。
我已经宣布了一个单独的变量'slideShow'。
var slideShow:SlideShow;
function addSlideShow(e:MouseEvent):void {
slideShow = new SlideShow();
addChild(slideShow);
}
function clearSlideshow (e:MouseEvent):void {
removeChild(slideShow);
}
如果我两次调用addSlideShow函数,将创建两个SlideShow类实例并将其添加到舞台中。
如果我两次调用clearSlideshow,则只从舞台中删除一个实例。第二个调用会产生错误。
我想每次调用addSlideShow时,变量slideShow都会被新的SlideShow实例覆盖,因此只会创建一个实例。显然情况并非如此。
考虑到这一点,以下是处理事物的正确方法,我在创建新实例之前删除并取消了slideShow变量吗?
var slideShow:SlideShow;
function addSlideShow(e:MouseEvent):void {
try {
removeChild(slideShow);
slideShow = null;
} catch (e:Error) {
trace(e);
}
slideShow = new SlideShow();
addChild(slideShow);
}
function clearSlideshow (e:MouseEvent):void {
try {
removeChild(slideShow);
slideShow = null;
} catch (e:Error) {
trace(e);
}
}
感谢您提供的任何帮助。
答案 0 :(得分:4)
变量没有被覆盖。使用new
创建的对象与设置为指向第一个幻灯片放映对象的引用slideShow
之间存在差异,然后设置为指向第二个幻灯片放映对象。这里发生的事情是,您不再对第一个对象有任何直接引用,因此您无法像尝试那样删除它。当然,在某个地方仍然有一个参考,因为对象是舞台的孩子。所以他们不会被垃圾收集。
常见的解决方案是在其中使用数组和push所有实例,因此您可以在以后删除它们。
在您的情况下,您还可以使用事件的目标来删除实例。
function addSlideShow(e:MouseEvent):void {
addChild(new SlideShow()); // don't need any explicit reference now.
}
function clearSlideshow (e:MouseEvent):void {
if(e.target is SlideShow){
removeChild(e.target);
}
}
答案 1 :(得分:1)
对clearSlideshow()的第二次调用失败,因为您没有任何指针指向要删除的元素:
首次调用addSlideShow():您创建了slideShow“A”。它是由slideShow var。
第二次调用addSlideShow():您创建了slideShow“B”。它是由slideShow var引用的。由于slideShow var已被覆盖,因此您不再引用“A”。
首次调用clearSlideshow():删除由slideShow指向的子节点,即“B”。
第二次调用clearSlideshow():你要求再次清除由slideShow指向的孩子,即“B”,但是这个孩子不在你的孩子列表中,因为它已被删除。
如果你想能够引用slideShows“A”和“B”,你必须保留一些东西,允许你引用它们中的任何一个(可能是一个幻灯片阵列)。
答案 2 :(得分:1)
第二次调用addSlideShow时,您只是丢失了引用 到第一个SlideShow对象。什么都没有被破坏,什么都没有被删除,这是垃圾收集器处理它。
但是如果使用addChild添加了之前的SlideShow对象,它仍然是 被添加它的父对象引用,所以垃圾收集器不会删除它。
如果您需要跟踪两个实例,则需要创建两个实例 参考对象。所以多个对象的最佳想法通常是 阵列。填写数组&从数组中删除。
由于父母会保留对所有孩子的引用
没有阵列也没有。只需迭代.children
或
通过getChildByName
方法识别它们。
答案 3 :(得分:0)
在您的第一个示例中,GC不会删除您添加的第一个SlideShow
,因为该阶段仍包含对它的引用。对removeChild()
的第二次调用失败,因为您提供的对象已经从舞台上删除了。
您的第二次尝试应该做您想要的,但您不需要将slideShow
设置为null
。由于您无论如何都要将新对象分配给slideShow
,因此不会再有对第一个实例的引用(除非您未显示的其他代码引用它),并且它将被GC删除。 / p>