`
ch_kexin
  • 浏览: 903121 次
  • 性别: Icon_minigender_2
  • 来自: 青岛
社区版块
存档分类
最新评论

AS3.0中遍历删除容器内子对象的误区

 
阅读更多
1 var a1:Sprite=new Sprite()
2 var a2:Sprite=new Sprite()
3 var a3:Sprite=new Sprite()
4 var a4:Sprite=new Sprite()
5 var a5:Sprite=new Sprite()
6 var a6:Sprite=new Sprite()
7 var a:Sprite=new Sprite();
8 a.addChild(a1)
9 a.addChild(a2)
10 a.addChild(a3)
11 a.addChild(a4)
12 a.addChild(a5)
13 a.addChild(a6)

a里面含有6个Sprite;
当使用for循环函数进行如下循环后
for(var i:uint=0;i<a.numChildren;i++){
    a.removeChildAt(i);
}

  一直以为a里面的所有子对象都被删除了,最近才发现实际上不是这样。
执行代码trace(a.numChildren);发现输出的是3,不是0。这说明a里面还有3个对象没有被删除。
为什么会这样呢?我们来分析下这句循环代码。发现a.numChildren在每次执行完a.removeChildAt(i);后发生了变化,
每次都减去了一,因为a里面的对象被删除了一个,所以a.numChildren会比原来少1。这样执行了3次循环后a.numChildren变成
3,i也变成3,3<3不成立退出循环。所以只有深度为0,1,2的被删除了,其他的还在,这样trace(a.numChildren);输出当然是
3了。
  既然这样把a.numChildren用个变量代替,即代码改为
var num:uint=a.numChildren;
for(var i:uint=0;i<num;i++){
    a.removeChildAt(i);
}
  这样每次循环的时候num就不会发生变化,就是会执行6次循环(a.numChildren=6)。这样应该不会错吧。
实际上运行时却出现如下错误

RangeError: Error #2006: 提供的索引超出范围。
    at flash.display::DisplayObjectContainer/removeChildAt()
    at _fla::MainTimeline/frame1()


  为什么会索引超出范围呢?再次分析下代码。发现num确实是固定不变了,但是a.removeChildAt(i);却出现了问题
由于as3新的的深度管理机制,当执行第一次循环后,深度为零的对象被删除,深度为1--5的对象的深度会自动减一。
因此深度为0的位置依然有对象存在。当三次循环后a.numChidlren变成3、i变成3。执行第四循环的时候会报错,因为
已经找不到索引为3位置的对象了。为了验证这种想法执行下面代码
代码
a1.name="a1";
a2.name="a2";
a3.name="a3";
a4.name="a4";
a5.name="a5";
a6.name="a6";

var num=a.numChildren;
try{
    for(var i:uint=0;i<num;i++){
        a.removeChildAt(i);
    }
}catch(e){}
for(var j:uint=0;j<a.numChildren;j++){
    trace(a.getChildAt(j).name)
}

分别给a里面每个子对象添加name属性,然后在执行遍历删除后,输出a里面还存在的对象的name。发现输出结果是a2、a4、a6。
这说明在遍历删除之前深度为奇数的对象被删除了,(为什么只有深度为奇数的对象被删除了,根据as3的深度管理机制揣摩下就能明白了)
  既然as3有这样的深度管理机制,那么不管怎么删除,深度为0位置的始终有对象存在。把代码改成

var num=a.numChildren;
for(var i:uint=0;i<num;i++){
    a.removeChildAt(0);
}
trace(a.numChildren);

就可以了,可以发现trace的结果是0,说明a里面的子对象全部被删除了。
注意:千万不要把for(var i:uint=0;i<num;i++)换成for(var i:uint=0;i<a.numChildren;i++),想想为什么?(原理跟上面的一样)
  如果觉得这样写麻烦的话,还可以用下面的写法

for(var i:uint=a.numChildren;i>0;i--){
    a.removeChildAt(0);
}

或者写成

for(var i:uint=a.numChildren;i>0;i--){
    a.removeChildAt(a.numChildren-1);
}

如果还觉得麻烦的话,还可以这样写

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

实际上我是在看到用while来遍历删除的方法后,才发现我以前用for来遍历删除的问题的,建议大家用最最后一种写法,这样写的代码最简单。

分享到:
评论

相关推荐

    Ext+3.0+API中文文档.rar

    2. **布局管理**:框架内置了多种布局模式,如fit、border、form、table等,用于控制容器内子组件的排列和大小调整,适应不同布局需求。 3. **数据绑定**:Ext JS支持数据模型(Model)、数据存储(Store)和数据...

    WinForm页面布局 控件

    在Windows Forms(WinForm)开发中,页面布局和控件的使用是构建用户界面的核心部分。WinForm提供了多种布局管理工具,帮助开发者有效地组织和排列控件,以创建美观、功能丰富的应用程序。在这个主题中,我们将深入...

    边界网关协议BGP实践课(7)-AS-Path属性

    AS_Path属性中的四种类型,它们分别是AS_Sequence、AS_Set、AS_Confed_Sequence和AS_Confed_Set,它们具体含义是: AS_Sequence:它是到目的地的路径上所经过的AS号的有序集合,按照顺序记录了路由经过的所有AS; AS...

    用js遍历 table的脚本

    在上述代码中,变量`z`代表当前单元格内子元素的索引,`tableObj.rows[i].cells[j].children[z]`取得第`i`行第`j`列单元格中第`z`个子元素对象。 对遍历到的每个元素,可以根据需要执行各种操作。例如,若想把每个...

    CSS旋转中的视差效果源码.rar

    如果源码中使用了自定义属性,那么它们可以用于统一管理和改变设计中的颜色、尺寸等值,而无需遍历整个样式表进行修改。 5. **响应式设计**:由于提到了适应不同屏幕尺寸,因此这个项目很可能考虑了响应式设计。这...

    类内子流形局部间隔对齐的人脸图像判别方法 (2010年)

    提出利用类内子流形对高维人脸图像进行判别分析的新方法,沿对齐的类间局部间隔法向扩展类内子图,获得一系列线性投影,并正交化线性投影得到一组子空间的正交基向量。使用局部相邻关系增大类间差异,并将类内结构保存到...

    微信小程序控件学习:view的flex布局《下》

    分享者:mayChunJ ;本文写于公测之前,如有出入,请以官方文档为准; 上一章即微信小程序之view的flex布局(1)里,我们学习了flex容器的属性,...下面我们来讲讲 flex-item的属性,在flex容器中,每个子元素就是一个f

    flex画线可以删除flex画线可以删除flex画线可以删除

    它允许开发者更加灵活地调整容器内子元素的排列、对齐和大小,尤其适合单行或多行内容的布局。 在Flex布局中,我们通常通过以下CSS属性来设置和管理容器和其子元素: 1. `display: flex` 或 `display: inline-flex...

    一张图了解flexbox布局.pdf

    Flexbox布局是CSS3新增的一种布局方式,它能够提供一种更加有效的方式来对页面中的容器内子元素进行排列、对齐和分配空间。Flexbox布局非常适合响应式设计,因为它允许我们轻松地改变子元素的排列顺序,以及在容器...

    内子口水库水生态修复工程初步设计方案评估方案报告.doc

    内子口水库水生态修复工程初步设计方案评估方案报告.doc

    JJHRENAME2020.exe

    个人批量文件重命名小工具,...1、遍历文件夹内子文件夹(只针对子文件有效)下所有文件进行重命名; 2、重命名时会根据子文件夹名称对里面的文件进行命名; 3、不提示直接执行重命名,并且无法撤回,请慎重!!!

    CSS3弹性盒模型开发笔记(二)

    此外,文档中还提及了box-orient属性,它用来控制弹性容器内子元素的排列方向。当box-orient属性被设置为horizontal时,子元素将沿水平方向排列。通过CSS前缀如-moz-和-webkit-,可以实现不同浏览器的兼容性。 总之...

    flex quick starts

    - **horizontalAlign** 和 **verticalAlign**:这两个属性分别用于控制容器内子组件在水平和垂直方向上的对齐方式。每个属性都有三个可选值:"left"/"top"(左/顶部对齐)、"center"/"middle"(居中对齐)以及"right...

    文件夹内子文件全局文本替换软件(适用android studio项目)

    本人是一名安卓开发者,由于没找到android studio的全局替换功能,于是我做了一个小工具,指定项目目录,指定欲替换的文本,用作替换的文本,遍历的文本后缀名,这些信息后,软件会自动全局替换符合条件的文件文本。...

    VC写的窗口截图工具,可截取当前名目中的所有控件

    在软件开发中,这种功能通常涉及到Windows API的使用,尤其是与窗口和控件相关的函数,如EnumChildWindows和GetWindowDC,用于遍历并捕获窗口内子窗口的图像。 描述中提到的“仿qq截图,并可实时截图,比QQ更好。按...

    FLEX小案例

    它的核心理念是提供一种更加灵活的方式来控制容器内子元素的排列、对齐和分配空间,无论容器的尺寸如何变化。 在“FLEX小案例”中,我们将探讨以下几个关键知识点: 1. **容器属性**: - `display: flex;`:这是...

    易语言最全面的类指针剖析源码

    在易语言中,“类指针”是一个重要的概念,它与面向对象编程紧密相关。在这个“易语言最全面的类指针剖析源码”中,我们可以深入理解类指针的使用方式及其在类继承、方法调用、变量访问等方面的关键作用。 类指针是...

    EXT 中文手册

    - **布局** 是 EXT 中用于定义容器内子元素排列方式的重要概念。EXT 提供了多种布局策略,如 CardLayout、BorderLayout 等。 - **简单的例子**:通过一个简单的示例展示了如何使用 EXT 的布局系统来组织页面内容。 ...

    Android HorizontalScrollView内子控件横向拖拽实例代码

    在Android开发中,HorizontalScrollView是一个非常有用的布局组件,它允许用户水平滚动其内容,尤其适用于需要展示多个横向排列的子视图的场景。本实例代码着重讲解如何在HorizontalScrollView中实现子控件的横向...

    Flex placement

    在Flexbox中,Flex Placement允许开发者精确控制弹性容器内子元素的位置和排列方式,以适应不同屏幕尺寸和设备类型。这个概念在响应式网页设计中尤其关键,因为它的目标是提供一种更加灵活、可扩展的方式来处理内容...

Global site tag (gtag.js) - Google Analytics