Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flash AS3重用变量_Flash_Actionscript 3 - Fatal编程技术网

Flash AS3重用变量

Flash AS3重用变量,flash,actionscript-3,Flash,Actionscript 3,我很难理解内存管理的基本原则是什么。希望有人能提供一个解释,这将帮助我更好地理解 我声明了一个类变量“slideShow” var slideShow:SlideShow; function addSlideShow(e:MouseEvent):void { slideShow = new SlideShow(); addChild(slideShow); } function clearSlideshow (e:MouseEvent):void { r

我很难理解内存管理的基本原则是什么。希望有人能提供一个解释,这将帮助我更好地理解

我声明了一个类变量“slideShow”

var slideShow:SlideShow;

function addSlideShow(e:MouseEvent):void {

    slideShow = new SlideShow();    
    addChild(slideShow);

}

function clearSlideshow (e:MouseEvent):void {

    removeChild(slideShow);

}
如果我调用函数addSlideShow两次,将创建SlideShow类的两个实例并将其添加到stage中

如果我调用ClearLideShow两次,则只会从阶段中删除一个实例。第二个调用创建了一个错误

我认为每次调用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);
    }   
}

感谢您提供的帮助。

第二次调用clearSlideshow()失败,因为您没有指向要删除的元素的指针:

  • 第一次调用addSlideShow():创建幻灯片“A”。它正被slideShow变量引用

  • 第二次调用addSlideShow():创建幻灯片“B”。它正被slideShow变量引用。由于slideShow变量已被覆盖,您不再有任何对“A”的引用

  • 第一次调用clearSlideshow():删除幻灯片所指向的子对象,即“B”

  • 第二次调用clearSlideshow():您要求再次清除幻灯片所指向的子项,即“B”,但该子项不在您的子项列表中,因为它已被删除


  • 如果您希望能够引用幻灯片“A”和“B”,则必须保留一些允许您引用其中任何一个的内容(可能是一组幻灯片)。

    在第一个示例中,您添加的第一个
    幻灯片不会被GC删除,因为该阶段仍然包含对它的引用。对
    removeChild()
    的第二次调用失败,因为您作为参数提供的对象已从阶段中删除

    您的第二次尝试应该可以执行您想要的操作,但您不需要将
    幻灯片放映设置为
    null
    。由于您正在将新对象分配给幻灯片放映,因此不会再有对第一个实例的引用(除非您没有显示的其他代码引用了它),并且它将被GC删除。

    该变量不会被覆盖。使用
    new
    创建的对象与设置为指向第一个幻灯片放映对象,然后设置为指向第二个幻灯片放映对象的参考
    slideShow
    之间存在差异。这里发生的事情是,你不再直接引用第一个对象,所以你不能像你尝试的那样删除它。当然,还有一个参考点,因为对象是舞台上的孩子。这样它们就不会被垃圾收集了

    常见的解决方案是使用一个数组和其中的所有实例,这样您就可以在以后删除它们

    在您的情况下,还可以使用事件的目标来删除实例

    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);
        }
    }
    
    • 第二次调用addSlideShow时,您将丢失引用 到第一个幻灯片放映对象。没有任何东西会被破坏,没有任何东西会被移除,这是由垃圾收集器来处理的

    • 但是,如果先前的幻灯片对象是使用addChild添加的,它仍然是 被添加到其中的父对象引用,因此垃圾收集器不会删除它

    • 如果需要跟踪两个实例,则需要创建两个单独的实例 引用对象。因此,多个对象的最佳方案通常是 数组。填充到阵列中并从阵列中移除

    • 由于父对象保留了对其所有子对象的引用,因此您可以获得 也没有阵列。只需迭代
      .children
      或 通过
      getChildByName
      方法识别它们