首页 > 设计 > WEB开发 > 正文

13.11.创建ArrayCollection的深度拷贝

2023-07-22 12:39:10
字体:
来源:转载
供稿:网友
13.11.1. 问题
我需要拷贝索引数组的所有数据项或对象到新对象上。
13.11.2. 解决办法
使用mx.utils.ObjectUtil.copy 方法。
13.11.3. 讨论
为了快速演示,我们简单的拷贝对象引用到新对象上,这意味着对第一个对象的值改变都会反映到第二个对象上:
+展开
-ActionScript
var objOne:Object = {name:"foo", data:{first:"1", second:"2"}};
var objTwo = objOne;
objOne.data.first = "4";
trace(objTwo.data.first);//traces 4

要想拷贝对象到另一个对象上,使用mx.utils.ObjectUtil 类。该方法接受一个对象参数,返回内存新地址上的该对象的深度拷贝。这意味着改变对象的所有属性都不会影响到原始对象,这样使用这个方法:
+展开
-ActionScript
var objTwo = mx.utils.ObjectUtil.copy(objOne);

该拷贝方法的工作原理是把原对象转换为ByteArray,然后再把ByteArray 写到新对象上,具体如下:
+展开
-ActionScript
var ba:ByteArray = new ByteArray();
ba.writeObject(objToCopy);
ba.position = 0;
var objToCopyInto:Object = ba.readObject();
return objToCopyInto;

现在应该能达到我们的目的了:
+展开
-ActionScript
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

用这个方法拷贝指定类型的对象却有些困难,如下面的代码将会抛出异常:
+展开
-ActionScript
var newFoo:Foo = ObjectUtil.copy(oldFoo) as Foo;

因为Flash Player 将不知道如何把ByteArray 转换到指定的类型,通过使用ByteArray,对象被序列化为ActionScript Message Format (AMF) 二进制数据,和Flash Remoting 序列化对象的方式一样。要想反序列化数据对象,改类型必须使用flash.net.registerClassAlias 方法事先在Flash Player 中进行注册,该方法注册这个类,以便所有该类型的对象都能被反序列化为该类型的对象。registerClassAlias 方法需要两个参数:
+展开
-ActionScript
public function registerClassAlias(aliasName:String, classObject:Class):void

第一个参数为类的完全限定类名,第二个参数为对象类型。完全限定类名类似于mx.containers.Canvas 或com.oreilly.cookbook.Foo。这个例子中,当拷贝对象时需要先知道类名或类引用。还好flash.utils.getQualifiedClassName 返回对象的完全限定类名, 而flash.utils.getDefinitionByName 返回类的类对象引用。通过使用这两个方法,你就可以注册任何对象的类了:
+展开
-ActionScript
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 对象中每个对象都可正确的拷贝到新对象上:
+展开
-ActionScript
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 方法则源ArrayCollection 中所有对象的数据将会丢失。但是每个对象的类信息还是在的,任何试图转换集合对象为原来类型时结果会是错误的或是null 值。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表