Flex Cookbook --13.11深度拷贝ArrayCollection

简介:

 

13.11 深度拷贝一个ArrayCollection集合
13.11.1 问题
需要拷贝一个索引数组里的所有项或者从一个对象创建一个新对象。
13.11.2解决
使用mx.utils.ObjectUtil.copy方法
13.11.3讨论
正如演示那样,copy一个对象仅仅是为新对象创建了一个指针。意味着对第一个对象值的任何改变都会反映到第二个对象上。
var objOne:Object = 
{name:"foo", data:{first:"1", second:"2"}}; 
var objTwo = objOne; 
objOne.data.first = "4"; 
trace(objTwo.data.first);//traces 4

相反如果我们想要copy一个对象的全部到另一个对象中,使用mx.utils.ObjectUtil类的copy方法。该方法接受一个对象做为参数而返回一个在内存的新位置的此对象的深度拷贝。
这就意味着该对象的任何属性被copy而不再是引用原始对象相同位置的属性。如下使用此方法:
var objTwo = mx.utils.ObjectUtil.copy(objOne);
此copy方法工作机制是通过原对象创建一个ByteArray,然后再把ByteArray写入一个新对象,如下所示:
        var ba:ByteArray = new ByteArray(); 
        ba.writeObject(objToCopy); 
        ba.position = 0; 
        var objToCopyInto:Object = ba.readObject(); 
        return objToCopyInto;

这样原来的例子就可以如期的执行:
var objOne:Object = {name:"foo", data:{first:"1", second:"2"}}; 
var objTwo = objOne; 
var objThree = mx.utils.ObjectUtil.copy(objOne); 
objOne.data.first = "4"; 
trace(objTwo.data.first);//traces 4 
trace(objThree.data.first);//traces 1, which is the original value
为了copy一个特定类型的对象为一个新对象存在一定难度。下面的代码会抛出一个错误:
var newFoo:Foo = ObjectUtil.copy(oldFoo) as Foo;
Flash Player并不知道如何把ByteArray转换为指定的类型。通过ByteArray,对象被序列化为AMF 二进制数据,这种方式和Flash Remoting中的一致。
为了反序列化此数据对象,该类型必须通过flash.net.registerClassAlias方法向Flash Player注册。此方法注册该类,以便该类的实例对象都可以从二进制反序列化回原对象。
registerClassAlias 需要2个参数:
public function registerClassAlias(aliasName:String, classObject:Class):void
第一个参数是此类的全类名,第二个参数是类型为Class的一个对象。全类名就是类似如下的mx.containers.Canvas or com.oreilly.cookbook.Foo. 
在这里的例子中,拷贝对象时既不知道全类名也不知道该类的一个引用。幸运的是,flash.utils.getQualifiedClass会返回参数传入的对象的全类名,而flash.utils.getDefinitionByName 
返回传入的对象的类引用。通过使用这2个方法,你可以注册任何对象的类:
private function copyOverObject(objToCopy:Object, registerAlias:Boolean = false):Object 

                    if(registerAlias) { 
                    var className:String = flash.utils.getQualifiedClassName(objToCopy); 
                    flash.net.registerClassAlias(className, 
(flash.utils.getDefinitionByName(className) as Class)); 
                    } 
        return mx.utils.ObjectUtil.copy(objToCopy); 
}
现在一个强类型对象的ArrayCollection就可以通过把集合中的每个对象传给copyOverObject方法正确的拷贝啦:
private function copyOverArray(arr:Array):Array { 

        var newArray:Array = new Array(); 
        for(var i:int; i<arr.length; i++) { 
        newArray.push(copyOverObject(arr[i], true)); 
        } 
        return newArray; 

var ac:ArrayCollection = new ArrayCollection([{name:'Joseph', id:21}, foo,    
{name:'Josef', id:81}, {name:'Jose', id:214}]); 
var newAC:ArrayCollection = new ArrayCollection(copyOverArray(ac.source)); 
值得注意的是,如果仅仅是通过mx.utils.ObjectUtil.copy来拷贝这2个ArrayCollection,那么原始ArrayCollection中的所有数据也会存在于新拷贝的ArrayCollection中。但是关于每个对象的类信息将不存在,任何企图
把该集合中一个对象强制转化为某一指定类型都将导致一个错误或空值。
 
 
 
译者注:
1.实验代码1
<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="alertObj();"> 
  <mx:Style> 
    Application{fontSize:12px;} 
  </mx:Style> 
  <mx:Script> 
    import mx.controls.Alert; 
     
    public function alertObj():void 
    { 
      var objOne:Object ={name:"张三", data:{first:"张", second:"三"}}; 
      var objTwo:Object = objOne; 
      objOne.data.first = "李";//对原始对象的修改,也会在新对象反应出来 
      Alert.show(objTwo.data.first);//输出 李    
    }    
  </mx:Script> 
</mx:Application>
 
 
2。实验代码2--深拷贝
<?xml version="1.0" encoding="utf-8"?> 
<!--对象的深度拷贝--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="alertObj();"> 
  <mx:Style> 
    Application{fontSize:12px;} 
  </mx:Style> 
  <mx:Script> 
    import mx.controls.Alert; 
    import mx.utils.ObjectUtil; 
     
    public function alertObj():void 
    { 
      var objOne:Object ={name:"张三", data:{first:"张", second:"三"}}; 
      var objTwo:Object =ObjectUtil.copy(objOne);//关键代码 
      objOne.data.first = "李";//对原始对象的修改,不会影响第二个 
      Alert.show("objOne="+objOne.data.first+"\nobjTwo="+objTwo.data.first);// 
    }    
  </mx:Script> 
</mx:Application>
 
 
3.对ArrayCollection深度拷贝
 
<?xml version="1.0" encoding="utf-8"?> 
<!--特定类对象的深度拷贝--> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="alertObj();"> 
  <mx:Style> 
    Application{fontSize:12px;} 
  </mx:Style> 
  <mx:Script> 
    <![CDATA[ 
    import mx.controls.Alert; 
    import mx.utils.ObjectUtil; 
    import mx.collections.ArrayCollection; 
     
    public function alertObj():void 
    { 
      var zl:Object={name:"赵六",age:29}; 
      var ac:ArrayCollection = new ArrayCollection([ 
                    {name:'张三', age:20}, 
                    zl,    
                    {name:'李四', age:31},    
                    {name:'王五', age:27} 
                    ]); 
      var newAC:ArrayCollection = new ArrayCollection(copyOverArray(ac.source)); 
        
      //可以如下验证下 
      //ac[2].name = "改变"; 
      //Alert.show(newAC[2].name); 
    }    
     
    //对一个对象数组深度拷贝 
    private function copyOverArray(arr:Array):Array { 
      var newArray:Array = new Array(); 
      for(var i:int;i<arr.length; i++){ 
        newArray.push(copyOverObject(arr[i], false));//深度拷贝每个元素 
      } 
      return newArray; 
    }    
     
    //对对象深度拷贝 
    private function copyOverObject(objToCopy:Object, registerAlias:Boolean = false):Object 
    { 
      if(registerAlias) { 
        var className:String = flash.utils.getQualifiedClassName(objToCopy); 
        flash.net.registerClassAlias(className,(flash.utils.getDefinitionByName(className) as Class)); 
      } 
      return mx.utils.ObjectUtil.copy(objToCopy); 
    }    
    ]]> 
  </mx:Script> 
</mx:Application>


本文转自 xcf007 51CTO博客,原文链接: http://blog.51cto.com/xcf007/101733 ,如需转载请自行联系原作者



 
相关文章
|
Java 开发工具 Android开发
超级高兴.flex builder 的插件拷贝可以 在 eclipse 3.5 里面运行.
做java的 打开 2 个eclipse 一个开发java 一个调试 flex builder 还是非常麻烦的..   突然有一个想法 既然都是 eclipse 拷贝下运行看看可以么...   发现真的可以..   以后的事情可是方便多了..   一边写 做 j2ee 一边 写 flex.     将 flex builder 下面的 plugin adobe
1130 0
|
5月前
|
开发者 容器
flex 布局属性在实际项目中的应用场景有哪些?
flex 布局属性在实际项目中的应用场景有哪些?
|
4月前
|
前端开发 UED 容器
使用 Flex 布局实现垂直居中效果
【10月更文挑战第7天】
504 57
|
3月前
|
容器
Bootstrap5 Flex(弹性)布局4
排序:.order 类可设置弹性子元素的排序,范围从 .order-1 至 .order-12,数字越小优先级越高。外边距:.ms-auto 和 .me-auto 分别用于设置子元素的右侧和左侧外边距为 auto。包裹:.flex-nowrap(默认)、.flex-wrap 和 .flex-wrap-reverse 用于控制弹性容器中的子元素是否换行及换行方向。
|
2月前
|
容器
Bootstrap5 Flex(弹性)布局6
使用 `.align-self-*` 类可控制指定子元素的对齐方式,包括 `.align-self-start`, `.align-self-end`, `.align-self-center`, `.align-self-baseline`, 和 `.align-self-stretch`。示例代码展示了如何在一个弹性布局中应用这些类,以实现不同设备上的响应式设计。
Bootstrap5 Flex(弹性)布局5
使用 .align-content-* 控制多行子元素在垂直方向上的堆叠方式,如 .align-content-start、.align-content-center 等。对于单行子元素,使用 .align-items-* 控制对齐,例如 .align-items-start、.align-items-center 等。示例代码展示了不同对齐效果的应用。
Bootstrap5 Flex(弹性)布局2
介绍Flex布局的水平和垂直方向控制。`.flex-row`使子元素水平排列,默认左对齐;`.flex-row-reverse`则右对齐。`.flex-column`让子元素垂直排列;`.flex-column-reverse`则反向排列。示例展示了不同类的效果,通过改变类名实现布局调整。
Bootstrap5 Flex(弹性)布局3
`.justify-content-*` 类用于调整弹性子元素的对齐方式,支持 start、end、center、between、around 等值。`.flex-fill` 类使所有子元素等宽,而 `.flex-grow-1` 则让指定子元素占据剩余空间。这些类在布局设计中非常实用。
|
3月前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。
|
3月前
|
容器
HTML中使用Flex布局实现双行夹批效果
在HTML中,还可以用table元素来实现双行夹批效果,但比flex布局代码更复杂,效果也不见得更理想。
73 10