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 ,如需转载请自行联系原作者



 
相关文章
|
3月前
|
编译器 PHP
深入浅出 Compose Compiler(4) 智能重组与 $changed 参数
深入浅出 Compose Compiler(4) 智能重组与 $changed 参数
39 5
深入浅出 Compose Compiler(4) 智能重组与 $changed 参数
|
3月前
|
存储 Rust C语言
【一起学Rust | 进阶篇 | Grid库】二维表数据结构——Grid
【一起学Rust | 进阶篇 | Grid库】二维表数据结构——Grid
80 0
|
8月前
|
存储 安全 编译器
[C++] C++入门第二篇 -- 引用& -- 内联函数inline -- auto+for(上)
[C++] C++入门第二篇 -- 引用& -- 内联函数inline -- auto+for(上)
|
8月前
|
存储 编译器 C语言
[C++] C++入门第二篇 -- 引用& -- 内联函数inline -- auto+for(下)
[C++] C++入门第二篇 -- 引用& -- 内联函数inline -- auto+for(下)
|
Java
JavaWeb - 深度拷贝方式和性能对比(一)
JavaWeb - 深度拷贝方式和性能对比(一)
226 0
|
SQL Oracle 关系型数据库
测试3——探究shrink和move原理
shrink操作的机制: 我们接下来讨论一下shrink的实现机制,我们同样使用讨论move机制的那个实验来观察.SQL> create table TEST_HWM (id int ,name char(2000)) tablespace ASSM;T...
919 0
|
vr&ar 图形学
【100个 Unity小知识点】 | Unity两种获取游戏对象的方法,GameObject.Find 和 Transform.Find区别
Unity 小科普 老规矩,先介绍一下 Unity 的科普小知识: Unity是 实时3D互动内容创作和运营平台 。 包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助 Unity 将创意变成现实。 Unity 平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。 也可以简单把 Unity 理解为一个游戏引擎,可以用来专业制作游戏!
【100个 Unity小知识点】 | Unity两种获取游戏对象的方法,GameObject.Find 和 Transform.Find区别