使用for进行removeChild的问题
碰到一个奇怪的问题,最后终于解决。其实是自己的疏忽。记在这里了:
下面的代码中,vs是一个ViewStack实例,removeVS的功能是移除VS中多余的子显示对象,以便对其中的子显示对象进行重建。在vs中原来有4个子显示对象copyright、step1、step2、stepUpload,它们不在移除范围之内。
1private function removeVS():void{
2 Logger.info('removeVS运行,删除前的vs子数量:{1}', vs.numChildren);
3 for(var i:int=0; i < vs.numChildren; i++)
4 {
5 Logger.debug('当前序号:{1}',i);
6 var __step:UIComponent = vs.getChildAt(i) as UIComponent;
7 var __isInitStep:Boolean = __step == copyright || __step == step1 || __step == step2 || __step == stepUpload;
8 Logger.info('当前的step name:{1},是否保留:{2},当前序号{3}', __step.name, __isInitStep, i);
9 if(!__isInitStep)
10 {
11 vs.removeChild(__step);
12 }
13 }
14 Logger.info('removeVS运行,删除后的vs子数量:{1}', vs.numChildren);
15}
在没有添加子显示对象之前,vs的子显示对象应该有4个,而一旦添加的其他的显示对象,当调用removeVS的时候,却只能移除一个添加的显示对象!
例如:我在vs中添加了一个step3和step4显示对象,在移除的时候,却仅仅移除了step3,而step4仍然保留!!!
这是怎么回事?经检查,发现问题出在vs.numChildren上。
因为for循环中引用的是vs.numChildren,而当__inInitStep为false的时候,vs移除了一个子显示对象。这时vs.numchildren就发生了变化,变为vs.numchildren-1。这导致循环少执行了一次,没有删掉step4。
找到了问题的原因,修改成如下代码:
1private function removeVS():void{
2 var __toRemovedArr:Array = new Array();
3 for(var i:int=0; i < vs.numChildren; i++)
4 {
5 Logger.debug('当前序号:{1}',i);
6 var __step:UIComponent = vs.getChildAt(i) as UIComponent;
7 var __isInitStep:Boolean = __step == copyright || __step == step1 || __step == step2 || __step == stepUpload;
8 if(!__isInitStep)
9 {
10 __toRemovedArr.push(__step);
11 }
12 }
13 for each(var k:UIComponent in __toRemovedArr)
14 {
15 vs.removeChild(k);
16 }
17}
2011-09-26更新:还有更新简单的两个办法
- 使用递减的for循环
- 使用while循环
详见评论中的回复1和回复4
- 文章ID:434
- 原文作者:zrong
- 原文链接:https://blog.zengrong.net/post/for-removechild/
- 版权声明:本作品采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可,非商业转载请注明出处(原文作者,原文链接),商业转载请联系作者获得授权。