【问题标题】:Copying/Cloning properties of an instance?复制/克隆实例的属性?
【发布时间】:2013-10-15 10:03:08
【问题描述】:

我有一个具有一堆属性的显示对象。我想要做的是克隆这个类。我知道在 AS3 中无法对自定义类进行深层复制,因此我只需要复制属性,然后通过克隆方法创建一个新实例,该实例具有与原始类完全相同的属性。

我在获取显示对象的所有属性时遇到了一些问题。当然,我可以一个一个地调用每个 var 并将其放入一个数组中,然后将该数组返回给克隆,如下所示:

function clone():Array
    array.push(displayObject.x);
    array.push(displayObject.y);
    array.push(displayObject.price);
    return array;

但这并不是真正的面向对象。所以我正在寻找获取所有对象属性的方法,然后我会将这些属性放入一个新对象中。

哦,我在 AS3 for Air 而不是 Flex 上运行,所以我不能使用 mx.utils.ObjectUtil,这是一种方法。

【问题讨论】:

  • 你能用flash.utils.describeType吗?
  • 不幸的是它不读取私有属性。
  • 无法访问私有和受保护的属性

标签: actionscript-3 variables properties copy clone


【解决方案1】:

您不能复制私有财产。您可以使用 ByteArray 来复制属性

Dog 是要克隆的目标类

public class Dog  {

    public function Dog()
    {
    }

    public function setName($name:String):void {
        name = $name;
    }

    public var subDogs:Array = [];

    public var age:int;

    private var name:String;
}

这里是如何克隆

var dog:Dog = new Dog();
dog.subDogs.push(new Dog());
dog.setName("puppy");
dog.age = 15;

registerClassAlias("vo.Dog", vo.Dog);
var dogA:Object = CloneUtil.copy(dog);

var d:Dog = copy(dog) as Dog;

private function copy(source:Object):* {

      var ba:ByteArray = new ByteArray();
      ba.writeObject(source);

      ba.position = 0;

      return ba.readObject();
 }

【讨论】:

  • +1 但您必须为每个自定义用户类型和向量 recusivly 注册ClassAlias(这里可能不是问题)
  • 就我而言,registerClassAlias 仅用于将包含 cfg 文件的字典序列化为 game.data 文件,并将数据文件反序列化为字典对象。所以我觉得可以接受。
【解决方案2】:
package
{
    import flash.display.Sprite;
    import flash.utils.Dictionary;
    import flash.utils.describeType;
    import flash.utils.getQualifiedClassName;

    public class DynamicClone extends Sprite
    {
        public function DynamicClone()
        {
            var p1 : Player = new Player;
            p1.name = "Simsoft";
            p1.hiddenAccessor = 10;

            var p2 : * = clone( p1 );

            // p2 is a Player instance
            trace(getQualifiedClassName( p2 )); // Player

            // p1 and p2 are not the same instance
            trace(p1 == p2); // False

            // But public properties are cloned
            trace(p2.name); // Simsoft
            trace(p2.hiddenAccessor); // 10
        }

        public function clone( source : Object, cloneGetSet : Boolean = true) : *
        {
            if( !source)
                return null;

            if( source is Array || source is Vector.<*> || source is Vector.<uint> || source is Vector.<int> || source is Vector.<Number> || source is Vector.<Boolean>)
                return source.concat();

            var newInstance : Object = new ( source.constructor );

            // Copy dynamic var
            for(var dynamicVar : String in source)
                newInstance[ dynamicVar ] = source[ dynamicVar ];

            var typeDescription : XML = describeType( source );

            // Copy variables
            for each(var variable : String in typeDescription..variable.@name)
                newInstance[ variable ] = source[ variable ];

            // Copy getter / setter
            if(cloneGetSet)
                for each(var getset : String in typeDescription..accessor.(@access == "readwrite").@name)
                    newInstance[ getset ] = source[ getset ];

            return newInstance;
        }
    }
}

internal class Player {

    // Will be clone
    public var name : String;

    // Won't be clone
    private var _score : uint;

    // Will be clone throught getter/setter
    private var _hidden : uint;

    // Can be clone because we have a getter and a setter
    public function get hiddenAccessor():uint
    {
        return _hidden;
    }

    public function set hiddenAccessor(value:uint):void
    {
        _hidden = value;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 2011-01-12
    • 2013-12-05
    • 2012-04-08
    • 1970-01-01
    • 2012-08-24
    • 2012-06-19
    相关资源
    最近更新 更多