碰到一个奇怪的问题,最后终于解决。其实是自己的疏忽。记在这里了:

下面的代码中,vs是一个ViewStack实例,removeVS的功能是移除VS中多余的子显示对象,以便对其中的子显示对象进行重建。在vs中原来有4个子显示对象copyright、step1、step2、stepUpload,它们不在移除范围之内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private function removeVS():void{
Logger.info('removeVS运行,删除前的vs子数量:{1}', vs.numChildren);
for(var i:int=0; i < vs.numChildren; i++)
{
Logger.debug('当前序号:{1}',i);
var __step:UIComponent = vs.getChildAt(i) as UIComponent;
var __isInitStep:Boolean = __step == copyright || __step == step1 || __step == step2 || __step == stepUpload;
Logger.info('当前的step name:{1},是否保留:{2},当前序号{3}', __step.name, __isInitStep, i);
if(!__isInitStep)
{
vs.removeChild(__step);
}
}
Logger.info('removeVS运行,删除后的vs子数量:{1}', vs.numChildren);
}

在没有添加子显示对象之前,vs的子显示对象应该有4个,而一旦添加的其他的显示对象,当调用removeVS的时候,却只能移除一个添加的显示对象!

例如:我在vs中添加了一个step3和step4显示对象,在移除的时候,却仅仅移除了step3,而step4仍然保留!!!

这是怎么回事?经检查,发现问题出在vs.numChildren上。

因为for循环中引用的是vs.numChildren,而当__inInitStep为false的时候,vs移除了一个子显示对象。这时vs.numchildren就发生了变化,变为vs.numchildren-1。这导致循环少执行了一次,没有删掉step4。

找到了问题的原因,修改成如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private function removeVS():void{
var __toRemovedArr:Array = new Array();
for(var i:int=0; i < vs.numChildren; i++)
{
Logger.debug('当前序号:{1}',i);
var __step:UIComponent = vs.getChildAt(i) as UIComponent;
var __isInitStep:Boolean = __step == copyright || __step == step1 || __step == step2 || __step == stepUpload;
if(!__isInitStep)
{
__toRemovedArr.push(__step);
}
}
for each(var k:UIComponent in __toRemovedArr)
{
vs.removeChild(k);
}
}

2011-09-26更新:还有更新简单的两个办法

  1. 使用递减的for循环
  2. 使用while循环

详见评论中的回复1和回复4

留言

2008-02-20
次访问