【问题标题】:AS3: How to Deep Copy an ObjectAS3:如何深度复制对象
【发布时间】:2014-05-24 04:40:53
【问题描述】:

我有一个对象需要复制到我的 SharedObject 数据中。 问题是共享对象的数据属性是只读的,所以我无法克隆我的“源”对象并将其分配给共享对象数据,我必须以这种方式复制它们:

var so: SharedObject = SharedObject.getLocal("appData");
copyObject(sourceObj, so.data);
so.flush();

以及复制方法:

public static function copyObject(sourceObject:Object, destinationObject:Object):void{
    // this would be the code that i need
}

还要记住,我的对象具有对象属性,因此它具有 n 个对象级别。这就是为什么我不能简单地为每个属性创建一个并在第一级分配所有属性,所以我需要做一个深度副本,可能是递归的。我尝试了几个小时来制作这个 copyObject 方法,但没有成功。我也在互联网上搜索过,但没有找到任何适合我的对象副本。

有人可以帮我用这个方法吗?我真的很感激!

感谢您的帮助!

【问题讨论】:

    标签: actionscript-3 flash object actionscript air


    【解决方案1】:

    解决方案是将您的对象写入字节数组,将其编码为字符串(可选 - 您可能也可以保存字节数组,尚未查找)并将其保存到您的共享对象。

    此函数将获取一个对象并将其转换为字符串

    public static function serializeToString(value:Object):String{
                            if(value==null){
                                throw new Error("null isn't a legal serialization candidate");
                            }
    
                            var bytes:ByteArray = new ByteArray();
                            bytes.writeObject(value);
                            bytes.position = 0;
                            return Base64.encodeByteArray(bytes);
    }
    

    这个将从字符串中获取您的对象。

    public static function readObjectFromStringBytes(value:String):Object{
    
                  var result:ByteArray =   Base64.decodeToByteArray( value) as ByteArray;
                      result.position = 0;
                      return result.readObject();
    
                    } 
    

    您可以在此处找到 Base 64 编码类 https://github.com/juancgarcia/screenshotify/blob/master/Downloadify-652377f/src/com/dynamicflash/util/Base64.as

    【讨论】:

    • 您完全可以将ByteArray 保存在共享对象中,无需额外编码。但是,为了使对象通过readObject() 有效读取,它必须能够被外部化(见我的回答)。
    【解决方案2】:

    您需要在所有要以这种方式存储的对象上实现IExternalizable。该实现包括在执行 writeObject() 时针对 ByteArray 调用 writeExternal 方法,以及针对新创建的实例调用 readExternal 方法,因此您的类应该编写必要的元数据以使您的对象深度克隆,包括编写属性对象。

    Manual on IExternalizable

    顺便说一句,您不应该在整个so.data 中存储一个对象,您最好在so.data 中分配一个字段并将您的对象副本填入其中。

    【讨论】:

      【解决方案3】:

      对于复杂的对象,我会使用 RegisterClassAlias:

      import flash.net.registerClassAlias;
      registerClassAlias("YourClassName", YourClassName);
      var so:SharedObject = SharedObject.getLocal("objectName");
      so.data.yourData = YourClassName.instance;
      so.flush();
      

      对于具有深层简单数据(包括数组的基元)的简单对象类型,我会在读取数据时简单地使用 JSON.stringify() 和 JSON.parse()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-25
        • 2012-12-15
        • 2023-03-17
        • 2012-07-03
        • 2014-11-03
        • 2018-01-28
        相关资源
        最近更新 更多