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,我会得到正确数量的要删除的图像。有人有同样的问题吗?

4

4 回答 4

5

尝试以相反的顺序删除它们。您可能会丢失删除,因为您试图在前向绑定循环中删除它们。

for(var i:int=container.numChildren;i>=0;i--)
{
     var currImg:Sprite = container.getChildAt(i) as Sprite;
     container.removeChild(currImg);
}
于 2011-05-20T17:06:15.133 回答
3

我也遇到过这个问题。这里真正的问题是您正在逐步浏览显示列表并在每次迭代时将其削减。在 AVM2 中,显示列表深度是在此上下文中自动管理的,当您移除一个子项时,显示列表深度的其余部分会被调整。无论如何,解决方案是将其包装在一个while循环中:

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

更新

还有一个关于您的代码的注释。尽量不要对剪辑进行新的引用。这将导致闪存 VM 中的垃圾收集过程出现问题,该过程是自动化的,只有使用弱引用取消引用或引用的对象才会被清理。因此,您可以执行以下操作之一:

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)));
}
于 2011-05-20T17:09:45.190 回答
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

现在,第一次通过循环,您删除 cat ,因为它在显示列表中的位置为 0。这是显示列表现在的样子:

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

请注意,显示列表索引已根据删除的子项发生变化。根据设计,显示列表上不能有间隙。

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

所以这是下一次循环之后的显示列表:

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

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

于 2011-05-20T17:44:10.587 回答
1

与@Michael 的回答类似,您的原始代码缺少删除,因为您的“numChildren”大小正在减少,并且您的迭代器在每个循环中都在增加:

正如@Ascension Systems 所指出的,这是最好的方法。

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...
于 2011-05-20T18:05:45.430 回答