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
1154 0
|
3月前
|
设计模式 容器
13.HarmonyOS流式卡片列表实现指南:Flex多行布局详解
在现代移动应用开发中,流式卡片列表是一种常见且实用的UI设计模式。它能够自适应屏幕宽度,在有限空间内高效展示多个内容项。本教程将详细讲解如何使用HarmonyOS的ArkUI框架中的Flex组件实现一个灵活的流式卡片列表,重点关注多行布局与对齐策略的应用。
96 2
|
3月前
|
开发者 UED 容器
07.精通HarmonyOS Flex对齐:从基础到高级布局技巧(上)
在HarmonyOS Next的ArkUI框架中,Flex容器提供了强大而灵活的对齐系统,使开发者能够精确控制子元素在容器中的排列方式。掌握这些对齐技术,是构建专业级用户界面的关键。
119 0
|
3月前
|
UED 容器
5.HarmonyOS Next开发宝典:掌握Flex布局的艺术
Flex布局(弹性布局)是HarmonyOS Next中最强大的布局方式之一,它提供了一种更加高效、灵活的方式来对容器中的子元素进行排列、对齐和分配空间。无论是简单的居中显示,还是复杂的自适应界面,Flex布局都能轻松应对。
140 0
|
3月前
|
UED 容器
10.HarmonyOS Next布局进阶:嵌套Flex容器与空间分配策略
在HarmonyOS Next的ArkUI框架中,Flex布局是构建用户界面的核心技术之一。通过嵌套使用Flex容器,我们可以创建复杂而灵活的界面结构,满足各种应用场景的需求。本教程将深入探讨如何在HarmonyOS Next中使用嵌套Flex容器实现复杂布局,以及如何合理分配和控制空间。
106 0
|
6月前
|
开发者 容器
鸿蒙开发:弹性布局Flex
在实际的开发中,需要掌握主轴与交叉轴的关系、换行规则及子元素属性,同时注意性能与兼容性问题,还有一点,Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用Column、Row代替。
171 10
鸿蒙开发:弹性布局Flex
|
12月前
|
开发者 容器
flex 布局属性在实际项目中的应用场景有哪些?
flex 布局属性在实际项目中的应用场景有哪些?
|
11月前
|
前端开发 容器
flex布局
【10月更文挑战第7天】
246 87
|
11月前
|
前端开发 UED 容器
使用 Flex 布局实现垂直居中效果
【10月更文挑战第7天】
1151 57
|
10月前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。