关于ActionScript深度数据对象拷贝

来源:互联网 发布:手机桌面美化软件 编辑:程序博客网 时间:2024/06/07 00:01

今天在天地会看见一篇帖子,关于深度拷贝对象的,很有感触,于是自己又就此做了一些细致的研究。原帖:

AS3隐藏特性——深拷贝数据对象

 

我们重点讨论一个数据对象的拷贝,而非显示对象的拷贝,因为Flash的显示对象是无法做到真正的深度拷贝的。

这里说的数据对象呢,一般是一个存储数据的VO类对象。

相信大部分人都知道用下面这种方法来进行对象的拷贝。

常规方法,简单,但不全面.

public function clone(sourceObj:*):*{    var b:ByteArray = new ByteArray();    b.writeObject(sourceObj);    b.position = 0;    return b.readObject();}


 

文章开始提到的天地会的帖子的方法有所改进,但是也有弊端,对于类里的对象(复合类对象)无法做到拷贝,于是我重新写了一个方法,能够完全的拷贝对象里的除显示对象以外的所有数据型变量。(至少经过测试,目前我是这么认为,如果有相左的发现,请告知,不胜感激)

代码如下:

package com.gdlib.util{    import flash.net.registerClassAlias;    import flash.utils.ByteArray;    import flash.utils.describeType;    import flash.utils.getDefinitionByName;    import flash.utils.getQualifiedClassName;    import flash.utils.getTimer;                            /**     * Object 工具类.     * @author Jack     * Email:  lovewqcm520@gmail.com     */    public class ObjectUtil    {        private static var aliasList:Array = [];                                        /**         * 复制一个对象         * @param sourceObj 要复制的源对象         * @param deep      是否对对象进行AMF序列化以后再深度复制         * @return          */        public static function clone(sourceObj:*, deep:Boolean=true):*        {            if(!sourceObj)                return null;                                                var lastTime:Number = getTimer();                                                if(deep)            {                // 得到  sourceObj的类名                var qualifiedClassName:String = getQualifiedClassName(sourceObj);                if(aliasList.indexOf(qualifiedClassName) == -1)                {                    // e.g  com.gdlib.test::RegisterClassAliasTest                    var packageName:String = qualifiedClassName.replace("::", ".");                    // 得到 sourceObj的类的类定义                    var classType:Class = getDefinitionByName(qualifiedClassName) as Class;                    // 注册此别名和类                    if(classType)                    {                        registerClassAlias(packageName, classType);                        aliasList.push(qualifiedClassName);                        trace("register class", packageName);                    }                                                                // 注册类公共属性(如果是复合类)                    registerVariables(sourceObj);                }            }                                                // 复制此对象            var b:ByteArray = new ByteArray();            b.writeObject(sourceObj);            b.position = 0;                                                trace("Clone object takes", getTimer()-lastTime, "ms.\n");            return b.readObject();        }                                        /**         * 注册某个类的公共属性(如果是复合类)所属的类的别名.         * @param sourceObj         */        private static function registerVariables(sourceObj:*):void        {            // 注册类公共属性(如果是复合类)            var xml:XML = describeType(sourceObj);            var variable:XML;            var variableType:String;            var variablePackageName:String;            var variableClassType:Class;                                                var variableXml:XMLList;            if(sourceObj is Class)                variableXml = xml.factory.variable;            else                variableXml = xml.variable;                                    //          <variable name="point" type="flash.geom::Point">//              <metadata name="__go_to_definition_help">//                <arg key="pos" value="209"/>//              </metadata>//          </variable>                                    //          <variable name="name" type="String">//              <metadata name="__go_to_definition_help">//                <arg key="pos" value="142"/>//              </metadata>//            </variable>                                                    for each (variable in variableXml)             {                variableType = variable.@type;                if(variableType.indexOf("::") != -1)                {                    if(aliasList.indexOf(variableType) == -1)                    {                        // "flash.geom::Point"  转换为     "flash.geom.Point"                        variablePackageName = variableType.replace("::", ".");                        variableClassType = getDefinitionByName(variableType) as Class;                        // 注册此别名和类                        if(variableClassType)                        {                            registerClassAlias(variablePackageName, variableClassType);                            registerVariables(variableClassType);                            aliasList.push(variableType);                            trace("register variable", variablePackageName);                        }                    }                }            }        }                                       }}


 

使用方法:

var source:RegisterClassAliasTest = new RegisterClassAliasTest();var result:RegisterClassAliasTest = ObjectUtil.clone(source);           trace(result is RegisterClassAliasTest);

缺点:为了达到较好的拷贝效果,此方法比较耗时,经过粗略测试,性能应该还能接受。

注意:复杂的显示对象(DisplayObject)无法达到真正的拷贝。

欢迎大家测试使用。

原创粉丝点击