2011-12-11 62 views
2

我很难理解我期望成为内存管理的基本原理。希望有人可以提供一个解释,这将有助于我更好地理解。AS3重复使用变量

我已经声明了一个类变量'slideShow'。

var slideShow:SlideShow; 

function addSlideShow(e:MouseEvent):void { 

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

} 

function clearSlideshow (e:MouseEvent):void { 

    removeChild(slideShow); 

} 

如果我调用该函数addSlideShow两次,将创建幻灯片类的两个实例,并添加到舞台上。

如果我调用clearSlideshow两次,则只有一个实例从舞台上移除。第二次调用会产生错误。

我在想我每次调用addSlideShow时,变量slideShow都会被新的SlideShow实例覆盖,因此只会创建一个实例。这显然不是这种情况。

考虑到这一点,下面是正确的方法来处理的事情,我创建一个新的实例之前,删除和null 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

该变量没有得到覆盖。您创建的对象与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

,因为你没有任何指针指的元素,你要删除到clearSlideshow()的第二个调用失败:

  1. 首先调用addSlideShow():创建幻灯片显示的“A” 。它正在被slideShow var引用。

  2. 第二次调用addSlideShow():您创建slideShow“B”。它正在被slideShow var引用。由于slideShow var已被覆盖,因此您不再有任何对“A”的引用。

  3. 第一次调用clearSlideshow():您删除了slideShow指向的子项,即“B”。第二次调用clearSlideshow():您要求再次清除slideShow所指向的孩子,即“B”,但是这个孩子并不存在于孩子列表中,因为它已被删除。

如果你希望能够提及幻灯片“A”和“B”,你必须坚持的东西,可以让你指任何人(也许幻灯片的数组)。

0

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

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

1
  • 你打电话addSlideShow第二次,你只是失去你参考 到第一幻灯片对象。没有东西会被破坏,没有东西会被删除,垃圾收集器可以处理它。

  • 但是,如果早期的SlideShow对象是使用addChild添加的,它仍然会被添加它的父对象引用,因此垃圾收集器不会删除它。

  • 如果您需要跟踪两个实例,则需要创建两个独立的 引用对象。所以多个对象的最佳想法通常是一个 阵列。填入阵列&从阵列中删除。

  • 由于家长保留对所有孩子的引用,因此您可以在没有数组的情况下获得 。简单地遍历.children或 由getChildByName方法识别它们。