AS3重用变量

时间:2011-12-11 13:06:24

标签: flash actionscript-3

我很难理解我期望成为内存管理的基本原则。希望有人可以提供一些解释,帮助我更好地理解。

我已经宣布了一个单独的变量'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);
    }   
}

感谢您提供的任何帮助。

4 个答案:

答案 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()的第二次调用失败,因为您没有任何指针指向要删除的元素:

  1. 首次调用addSlideShow():您创建了slideShow“A”。它是由slideShow var。

  2. 引用的
  3. 第二次调用addSlideShow():您创建了slideShow“B”。它是由slideShow var引用的。由于slideShow var已被覆盖,因此您不再引用“A”。

  4. 首次调用clearSlideshow():删除由slideShow指向的子节点,即“B”。

  5. 第二次调用clearSlideshow():你要求再次清除由slideShow指向的孩子,即“B”,但是这个孩子不在你的孩子列表中,因为它已被删除。

  6. 如果你想能够引用slideShows“A”和“B”,你必须保留一些东西,允许你引用它们中的任何一个(可能是一个幻灯片阵列)。

答案 2 :(得分:1)

  • 第二次调用addSlideShow时,您只是丢失了引用 到第一个SlideShow对象。什么都没有被破坏,什么都没有被删除,这是垃圾收集器处理它。

  • 但是如果使用addChild添加了之前的SlideShow对象,它仍然是 被添加它的父对象引用,所以垃圾收集器不会删除它。

  • 如果您需要跟踪两个实例,则需要创建两个实例 参考对象。所以多个对象的最佳想法通常是 阵列。填写数组&从数组中删除。

  • 由于父母会保留对所有孩子的引用 没有阵列也没有。只需迭代.children或 通过getChildByName方法识别它们。

答案 3 :(得分:0)

在您的第一个示例中,GC不会删除您添加的第一个SlideShow,因为该阶段仍包含对它的引用。对removeChild()的第二次调用失败,因为您提供的对象已经从舞台上删除了。

您的第二次尝试应该做您想要的,但您不需要将slideShow设置为null。由于您无论如何都要将新对象分配给slideShow,因此不会再有对第一个实例的引用(除非您未显示的其他代码引用它),并且它将被GC删除。 / p>