AS3 DeepCopy Utility Class

In ActionScript 3 when you create an object and set it’s value to that of an existing object, both the new object and the original object point to the same reference. This is known as creating a “shallow copy” of the original object. In a shallow copy, only a reference to the original object is created rather than creating a copy of the object directly.

For instance if you were to do the folowing:

var objA:Object = {id: “Object A: Original ID”};
var objB:Object = {id: “Object B: Original ID”};
var arrA:Array = new Array(objA, objB);
var arrB:Array = arrA;
objA.id = “Some new value”;
trace(arrA[0].id);
trace(arrB[0].id);
outputs:
“Some new value”
“Some new value”

As you can see in the example this can potentially cause problems if you need the indices in the array to not reflect changes in the objects in which they reference. In order to resolve this we would need to make what is known as a ‘deep copy’ of the objects in the Array. In a deep copy the objects that are being referenced are copied to a new memory location rather then pointing to the location of the reference objects themselves.

I wrote a simple class that uses a ByteArray to create a deep copy of the original objects. So if you wanted to create copies of the original Objects you could do so as in the following:

var objA:Object = {id: “Object A: Original ID”};
var objB:Object = {id: “Object B: Original ID”};
var arrA:Array = new Array(objA, objB);
var arrB:Array = DeepCopy.clone(arrA);
objA.id = “Some new value”;
trace(arrA[0].id);
trace(arrB[0].id);
outputs:
“Some new value”
“Object A: Original ID”

Below I have provided a link to view the source code.

DeepCopy

{ 3 comments to read ... please submit one more! }

  1. I get
    Type Coercion failed: cannot convert Object@22c8ca61 to com.thed.utils.HashMap

    when I try to cast the cloned object back. Any idea?

  2. I also get this same error. How do you avoid this error?

  3. Yes, this will only deep copy a native object. In order to cast a class object you will need to call registerClassAlias(…); and then type cast the object.

    You can do so as in the following:

    package {

    import flash.net.registerClassAlias;
    import mx.utils.ObjectUtil;

    public final class DeepCopy {
    public static function clone(instance:Object, alias:String, Type:Class) : * {
    registerClassAlias( alias, Type );
    return Type(ObjectUtil.copy( instance )) ;
    }
    }
    }

    Keep in mind if the Class constructor takes any arguments this will not work as you will get a #1063 RTE: Argument count mismatch… You will need to create your own deserialization API to handle constructor arguments as cloning an object will create a new instance which matches that of the cloned instance thus calling new on the Class object.

    I will update the DeepCopy class to implement the above method.

{ 0 Pingbacks/Trackbacks }