以前在《ActionScript殿堂之路》上就看到过的“深拷贝”概念一直没有好好地在实战中用到过,但是最近在开发过程中,我发现我在编写VO数据对象时的一个老习惯很浪费我的编码时间,这个习惯是这样的,我要为一个VO对象写一个clone复制方法来产生一个该对象的副本,我习惯的做法如下:
01.package
02.{
03.import flash.net.registerClassAlias;
04.import flash.utils.ByteArray;
05.import flash.utils.getDefinitionByName;
06.import flash.utils.getQualifiedClassName;
07.
08.public class MyVO
09.{
10.public var id:String;
11.
12.public var name:String;
13.
14.public function MyVO()
15.{
16.}
17.
18.public function clone():MyVO
19.{
20.var vo:MyVO = new MyVO();
21.vo.id = this.id;
22.vo.name = this.name;
23.
24.return vo;
25.}
26.}
27.}

在这个clone方法中我要做的事情很多,就是机械式地把我该VO类中全部声明的属性都逐个地赋值给新的一个VO类,这样做非常浪费代码量,而且每新增一个属性还需要同时修改clone方法,如我新增一个属性叫sex,就必须添加如下代码:
01.public class MyVO  
02.{   
03.public var sex:int;  
04.......         
05.public function clone():MyVO   
06.{      
07..........
08.vo.sex = this.sex;
09.return vo;  
10.}
11.}

而且如此做,在使用“继承”时非常不便,比如我创建一个MyVO2,它继承了MyVO,那么它自然也继承了MyVO的clone方法,不过我们发现其在调用clone方法后返回的结果为MyVO对象,而非MyVO2对象,此时还必须重载clone方法来让返回类型正确:
01.public class MyVO2  
02.{   
03.public var width:Number;  
04.
05.override public function clone():MyVO   
06.{      
07.var vo:MyVO2 = new MyVO2();//类型改成MyVO2
08.vo.id = this.id;
09.vo.name = this.name;
10.vo.sex = this.sex;
11.vo.width = this.width;
12.return vo;  
13.}
14.}

于是我就想到了使用深拷贝试试看行不行,就重构了一下我的clone方法:01./**
02.* 完全克隆此对象
03.* @return
04.*
05.*/     
06.public function clone():MyVO
07.{
08.var copier:ByteArray    = new ByteArray();
09.copier.writeObject(this);
10.copier.position     = 0;
11.
12.return copier.readObject() as MyVO;
13.}

但是这么写了之后,我调用clone方法发现返回结果为null,这究竟是怎么回事?what the hell is going on?经调试后发现,调用copier这个ByteArray对象的readObject方法后返回的是一个Object类型的对象,而非MyVO这个我要拷贝的类型。如何才能让其深拷贝得到的对象类型符合要求呢?我找到了flash.net.registerClassAlias这个方法,貌似可行,先看看AS3语言参考手册中对其的描述:------------------------------------------------------------------------------------------------------------------------------------

registerClassAlias

()

函数

 

public function registerClassAlias(aliasName:String, classObject:Class):void

语言版本:

ActionScript 3.0

运行时版本:

AIR 1.0 Flash Player 9

当以 Action Message Format (AMF) 对一个对象进行编码时,保留该对象的类(类型)。将对象编码为 AMF 时,该函数将保存该对象的类的别名,以便在解码对象时可以恢复该类。如果编码上下文没有为对象的类注册别名,该对象将被编码为一个匿名对象。同样,如果解码上下文注册了不同的别名,将为解码后的数据创建一个匿名对象。LocalConnection、ByteArray、SharedObject、NetConnection 及 NetStream 均为将对象编码为 AMF 的类的示例。编码和解码上下文不必对别名使用相同的类。它们可以主动地改变类,条件是目标类包含源类序列化的所有成员。 参数

 

aliasName:String — 要使用的别名。

   
 

classObject:Class — 与给定别名相关联的类。

示例

此示例使用 registerClassAlias() 函数为 ExampleClass 注册一个别名 ( com.example.eg )。由于为类注册了别名,因此可以将对象作为 ExampleClass 的实例反序列化,且代码将输出 true。如果删除 registerClassAlias() 调用,则代码将输出 false。
package {
    import flash.display.Sprite;
    import flash.net.registerClassAlias;
    import flash.utils.ByteArray;

public class RegisterClassAliasExample extends Sprite {
        public function RegisterClassAliasExample() {
            registerClassAlias("com.example.eg", ExampleClass);
            var eg1:ExampleClass = new ExampleClass();
            var ba:ByteArray = new ByteArray();
            ba.writeObject(eg1);
            ba.position = 0;
            var eg2:* = ba.readObject();
            trace(eg2 is ExampleClass); // true
        }
    }
}

class ExampleClass {}
------------------------------------------------------------------------------------------------------------------------------------看起来不错哦,让我们接下来试试看:

01.public function clone():Object
02.{
03.var typeName:String     = getQualifiedClassName(this);//获取当前类完全类名
04.var packageName:String  = typeName.split("::")[0];//截取命名空间之前的包名
05.var type:Class          = getDefinitionByName(typeName) as Class;//获取当前类定义
06.
07.registerClassAlias(packageName, type);//使用当前类的包名作为类别名,类定义作为注册类
08.
09.var copier:ByteArray    = new ByteArray();
10.copier.writeObject(this);
11.copier.position         = 0;
12.
13.return copier.readObject();
14.}

registerClassAlias的第一个参数为要使用的别名,我觉得这个别名随便取什么都不会有影响,不过为了规范起见,还是将别名设置为当前类的包名好了。此时调用clone方法发现能够如预期那样得到正确类型的对象,且保留了和拷贝源一致的所有属性,耶!拷贝成功!而且使用这招可以在使用继承的时候不必写任何冗余代码,即MyVO的任何子类都不需要重写clone方法也能正常工作。知道此方法的人撸过就好了,不知道的人记一下哦,省得和我以前一样,加重编码负担。不过需要注意哦,深拷贝对显示对象(DisplayObject)不起作用~

flex“深拷贝”的更多相关文章

  1. es6 Object.assign ECMAScript 6 笔记(六) ECMAScript 6 笔记(一) react入门——慕课网笔记 jquery中动态新增的元素节点无法触发事件解决办法 响应式图像 弹窗细节 微信浏览器——返回操作 Float 的那些事 Flex布局 HTML5 data-* 自定义属性 参数传递的四种形式

    es6 Object.assign   目录 一.基本用法 二.用途 1. 为对象添加属性 2. 为对象添加方法 3. 克隆对象 4. 合并多个对象 5. 为属性指定默认值 三.浏览器支持 ES6 O ...

  2. OpenCASCADE Expression Interpreter by Flex & Bison

    OpenCASCADE Expression Interpreter by Flex & Bison eryar@163.com Abstract. OpenCASCADE provide d ...

  3. Flex 布局教程:语法篇

    作者: 阮一峰 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...

  4. Flex 布局教程:实例篇

    该教程整理自 阮一峰Flexible教程 今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. 我的主要参考资料是Landon Schropp的文章和Solved ...

  5. python之浅拷贝和深拷贝

    1.浅拷贝 1>赋值:从下面的例子我们可以看到赋值之后新变量的内存地址并没有发生任何变化,实际上python中的赋值操作不会开辟新的内存空间,它只是复制了新对象的引用,也就是说除了b这个名字以外 ...

  6. python的拷贝(深拷贝和浅拷贝)

    今天看了几篇关于python拷贝的博文,感觉不太清楚,所以我就自己做实验试一下,特此记录. 拷贝是针对组合对象说的,比如列表,类等,而数字,字符串这样的变量是没有拷贝这一说的. 实现拷贝有: 1.工厂 ...

  7. C# 深拷贝的具体代码的封装与调用

    先封装下实现方法: public class DeepClone { public static object CopyObject(Object obj) { if (obj == null) { ...

  8. CSS布局之div交叉排布与底部对齐--flex实现

    最近在用wordpress写页面时,设计师给出了一种网页排布图样,之前从未遇到过,其在电脑上(分辨率大于768px)的效果图如下: 而在手机(分辨率小于等于768px)上要求这样排列: 我想到了两种方 ...

  9. Flexible 弹性盒子模型之flex

    实例 让所有弹性盒模型对象的子元素都有相同的长度,忽略它们内部的内容: #main div { flex:1; } 复制 效果预览 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号. 紧跟 ...

随机推荐

  1. 【Java】多线程

    class RunnableDemo implements Runnable { private Thread t; private String threadName; RunnableDemo( ...

  2. leetCode题解之修剪二叉查找树

    1.题目描述 Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so ...

  3. Ionic Css样式详解

    Header是固定在屏幕顶部的组件.可以包含如标题和左右的功能按钮.Sub Header同样是固定在顶部,只是是在Header的下面,就算没有写Header这个,Sub Header这个样式也会距离顶 ...

  4. B2B 电商业务之 Quote

    商品在网店页面上一般会向买家显示价格.对于B2B, 同一商品对不同的买家可能会展示不同的价格.即使如此,买家仍然可以和卖家再协商价格,最终以不同于网店中显示的价格成交.这个协商价格过程就叫Quote, ...

  5. sqlserver 统计信息自动更新 ----trace flag 2371

    对于已经应用的表(非临时表)统计信息更新条件为500+20%,具体更新条件 If the statistics is defined on a regular table, it is out of ...

  6. 使用 Azure CLI 管理 Azure 虚拟网络和 Linux 虚拟机

    Azure 虚拟机使用 Azure 网络进行内部和外部网络通信. 本教程将指导读者部署两个虚拟机,并为这些 VM 配置 Azure 网络. 本教程中的示例假设 VM 将要托管包含数据库后端的 Web ...

  7. jenkins+gitlib+git+mysql5.6+sonarqube+sonarrunner

    1. sonarrunner配置: 2. 未完待续....

  8. 铁乐学python_day09_作业

    练习题 1.整理函数相关知识点,写博客 2.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素, 并将其作为新列表返回给调用者. def odd_index(l): lis = [] for ...

  9. 将一个文件中的内容,在另一个文件中生成. for line in f1, \n f2.write(line)

    将一个文件中的内容,在另一个文件中生成. 核心语句: for line in f1: f1中的所有一行 f2.write(line)                                  ...

  10. JXL API总结

    API参考: http://www.andykhan.com/jexcelapi/index.html 官网: http://jexcelapi.sourceforge.net/ 1. 创建可写的工作 ...