使用for进行removeChild的问题

  • 本站文章除注明转载外,均为本站原创或者翻译。
  • 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商;
  • 本站部分原创和翻译文章提供markdown格式源码,欢迎使用文章源码进行转载;
  • 本博客采用 WPCMD 维护;
  • 本文标题:使用for进行removeChild的问题
  • 本文链接:http://zengrong.net/post/434.htm

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

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

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。

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

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