as3二进制深层次克隆
二进制深层次克隆(彻底摆脱了对原型(源对象)的影响和依赖)
特点:
1. 不能访问函数,只能访问属性
2. 使用bytearray克隆,不好的就是克隆出来的Object并非原应用类型,而且只可以克隆public属性。
它适用于在AS3中定义的数据类型,包括所有基元类型及由基元类型组合的复合类型,却并适用于在FP中定义的显示对象类型,如Sprite,MovieClip等。
注:基元类型指String, Number, uint, int, Object,Null, Boolean,void。貌似这样我们就可以实现对象的深拷贝了,但这个方法是有局限的。
AS3的效率(注意,我说的是AS3,而不是AVM)直接而言就是对于设计模式及算法的优化和对于对象操作的效率,
对于设计模式和算法的优化建立在对于AS3程序的架构和细节上的优化,需要应用的架构分析人员和程序员有一定深厚的“内力”。
而对于对象本身的操作效率的优化,则是建立在AS3官方的内置类提供的丰富功能上而言的。
今天就讨论一下对于对象操作的效率提升的话题,简单来说,就是讨论基于ByteArray类的操作方法。
从使用场景上来分析,单纯的存储一个String,Number,Boolean或者是略微复杂一些的XML数据片到内存中(实际上是AS3经过AVM的编译机制),
还比较不出来使用ByteArray的优势。但是一旦使用场景变为一个多人聊天室或者是分析一个服务提供的Heavy XML数据对象时,
使用ByteArray的效率就体现出来了。因为ByteArray直接使用AMF来对于数据序列化。
AMF是每个AS开发者都应该了解的一个协议,官方对于AMF在数据上的压缩功能的解释是可以和zlib相兼容和媲美的。
那么说到底,如何通过ByteArray操作对象,甚至是从内存中深层次的进行对象克隆呢?官方文档上给出的代码是最直观的(test函数)上述的Object拷贝用法总结起来有三个特点:
1.从内存中拷贝数据对象
2.自动使用AMF压缩序列化数据
3.生成的新的数据对象的拷贝,没有原来数据对象的类关联。比如objSource原来是ObjClass的关联,但是myNewObjectCopy则与ObjClass类没有关联。
实例如下:
package{
public class User{
private var _firstName:String;
private var _lastName:String;
public function set firstName (firstName:String):void{
_firstName = firstName;
}
public function set lastName (lastName:String):void{
_lastName = lastName;
}
public function get firstName():String{
return _firstName;
}
public function get lastName ():String{
return _lastName;
}
public function tosay($value:String):String{
return $value;
}
}
}
package{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.errors.EOFError;
import flash.utils.ByteArray;
public class ZzTest4 extends Sprite{
public function ZzTest4(){
var user:User = new User();
user.firstName = "xue";
user.lastName = "chong";
user.tosay("hello");
var user2:Object = cloneObject(user);
trace(user2.firstName, user2.lastName, user2 is User); //xue chong false
user.firstName = "ca*";
user.lastName = "nana";
trace(user2.firstName, user2.lastName, user2 is User); //xue chong false
var spr:Sprite = new Sprite();
spr.alpha = 0.5;
var spr2:Object = cloneObject(spr);
trace(spr2.alpha, spr2 is Sprite); //0.5 false
spr.alpha = 0.2;
trace(spr2.alpha, spr2 is Sprite); //0.5 false
}
/**
* 二进制深层次克隆方法
* */
public function cloneObject($obj:Object):Object{
var byteArray:ByteArray = new ByteArray();
byteArray.writeObject($obj);
byteArray.position = 0;
return(byteArray.readObject());
}
/**
* ByteArray类官方克隆原理(二进制深层次克隆)测试
* */
private function test():void{
var byteArr:ByteArray = new ByteArray();
byteArr.writeBoolean(false);
trace(byteArr.length); //1
trace(byteArr[0]); //0
byteArr.writeDouble(Math.PI);
trace(byteArr.length); //9
//以下trace均是AMF压缩之后的整数位和小数位的值,并非原来的3.1415...
trace(byteArr[0]); //0
trace(byteArr[1]); //64
trace(byteArr[2]); //9
trace(byteArr[3]); //33
trace(byteArr[4]); //251
trace(byteArr[5]); //84
trace(byteArr[6]); //68
trace(byteArr[7]); //45
trace(byteArr[8]); //24
byteArr.position = 0;
try{
trace(byteArr.readBoolean() == false); //true
}catch(e:EOFError){
trace(e); //EOFError: Error #2030: End of file was encountered.
}
try{
//使用ByteArray类的readDouble读取浮点数的方法提取内存中该浮点数,而且自动通过AMF还原数据,相当方便
trace(byteArr.readDouble()); //3.141592653589793
}
catch(e:EOFError){
trace(e); //EOFError: Error #2030: End of file was encountered.
}
try{
trace(byteArr.readDouble());
}catch(e:EOFError){
trace(e); //EOFError: Error #2030: End of file was encountered.
}
}
}
}