2011-05-20 24 views
2

我有一堆图像。 这些图像都加入到一个精灵容器:无法删除精灵容器的所有图像

var container:Sprite = new Sprite(); 
container.addChild(img);//added in a loop 
addChild(container); 

后来,当我通过容器循环,除去我说的图片:

for(var i:int=0;i<container.numChildren;i++) 
{ 
    var currImg:Sprite = container.getChildAt(i) as Sprite; 
    container.removeChild(currImg); 
} 

只有图像的一部分被删除。如果我跟踪container.numChildren,我会得到正确数量的要删除的图像。 有人有同样的问题吗?

回答

3

我也遇到过这个问题。这里真正的错误在于,您正在逐步完成显示列表,并在每次迭代时削减显示列表。在AVM2中,显示列表深度在此上下文中自动进行管理,而当您移除一个孩子时,将调整显示列表深度的其余部分。总之,解决的办法是把它包起来在一个while循环:

while(container.numChildren > 0){ 
    container.removeChildAt(0); 
} 

更新

另外一个音符你的代码。尽量不要对剪辑施加新的引用。这将导致闪存虚拟机中的垃圾收集过程出现问题,该虚拟机是自动化的,只有对象被解引用或使用弱引用引用才会被清除。所以,你可以做下列操作之一:

for(var i:int=0;i<container.numChildren;i++) 
{ 
    var currImg:Sprite = container.getChildAt(i) as Sprite; 
    container.removeChild(currImg); 
    currImg = null; 
} 

for(var i:int=0;i<container.numChildren;i++) 
{ 
    container.removeChild(Sprite(container.getChildAt(i))); 
} 
+0

另一件事是关于人们发布的代码+你自己的代码。在for循环中,您正在循环中投射变量“i”。尽量避免这种情况。在循环外部投射int,以便可以在for循环外部访问范围内的“i”,并在运行循环之后取消引用(即,在使用for循环的情况下)。循环不需要这个)。 – 2011-05-20 17:16:19

+0

“while”的方法完美工作,谢谢 – algro 2011-05-20 17:50:28

+0

for循环将工作,如果你改变getChildAt(i)getChildAt(0) – 2011-05-20 18:02:18

5

尝试以相反的顺序移除它们。可能是因为你想在正向循环中删除它们而丢失了删除。

for(var i:int=container.numChildren;i>=0;i--) 
{ 
    var currImg:Sprite = container.getChildAt(i) as Sprite; 
    container.removeChild(currImg); 
} 
+0

这正是他的问题,当他在索引0处移除孩子时,索引1处的孩子转移到索引0,然后在循环的下一次迭代中,他将索引1处的孩子移除,使索引0处的孩子离开索引0 – 2011-05-20 17:46:58

+1

@The_asman是,但如果你从最高n开始删除它们然后下降到0,所有这些都将被删除(包括第0个位置)。尝试一下。 – 2011-05-20 17:48:29

+0

是的,我同意你的说法,为什么我+1大声笑只是指出为什么他的破产。 – 2011-05-20 18:04:47

1

此代码将工作:

while(container.numChildren > 0) 
{ 
    container.removeChildAt(0); 
} 

但是我想指出的是错的循环,使你了解正在发生的事情。将我添加到您的代码中的跟踪添加到您的代码中。 :

for(var i:int=0;i<container.numChildren;i++) 
{ 
    trace (i + " : " + container.numChildren); 
    var currImg:Sprite = container.getChildAt(i) as Sprite; 
    container.removeChild(currImg); 
} 

您会看到每次循环时,子级的数量都会按预期减少。

但是,你需要明白的是,当一个孩子被删除 - 容器的显示列表发生了非常重要的变化。

下面是在运行循环之前显示列表的外观示例 - 我在前面显示的数字是它们在容器显示列表上的位置。

0-cat 
1-dog 
2-bird 
3-cow 
4-elephant 
5-clown 

现在,第一次通过循环,你删除猫,因为它的位置是0在显示列表上。以下是显示列表现在的样子:

0-dog 
1-bird 
2-cow 
3-elephant 
4-clown 

请注意,显示列表索引已根据删除的子级进行了移位。设计中不能在显示列表上留下间隙。

所以,下一次通过循环,我的值是1 - 对吗?这意味着“鸟”将从显示列表中删除,而不是狗,这是您可能预期的。

所以这里通过循环下一次后显示列表:

0-dog 
1-cow 
2-elephant 
3-clown 

所以,是的。这些解决方案中的许多都可行。在这种情况下,我建议使用while循环。但我认为从这个问题中获得的真正知识是理解这个问题。

1

到@迈克尔的回答一样,你原来的代码失踪清除,因为你的“numChildren的”大小减少和你的迭代器的每一个回路增加了对:

由于@Ascension系统指出,这是最好的办法。

while(container.numChildren > 0){ 
    container.removeChildAt(0); 
} 

但是,如果您确实想要在循环中执行此操作,则需要反向操作。

for(var i:int=container.numChildren;i>=0;i--){ 
    container.removeChild(container.getChildAt(i)); 
} 

为了说明在你原来的代码会发生什么情况,注意到有25名儿童在下面的例子:

如果在正向环路中删除,这是发生了什么(在每次迭代):

i:0 Array length:24 
i:1 Array length:23 
i:2 Array length:22 
i:3 Array length:21 
i:4 Array length:20 
i:5 Array length:19 
i:6 Array length:18 
i:7 Array length:17 
i:8 Array length:16 
i:9 Array length:15 
i:10 Array length:14 
i:11 Array length:13 
//the remaining 12 items never get looped over...