如何在ActionScript中创建对象的未引用副本

nxowjjhe  于 2022-09-21  发布在  Apache
关注(0)|答案(4)|浏览(157)

我有一个充满定制对象的ArrayCollection。我需要能够创建这个阵列的副本,执行一些功能和修改阵列和里面的对象。然后,我需要基本上将其重置为开始之前的原始存储副本。

问题(也是我发现并正在尝试修复的错误)是,我似乎无法创建不直接引用原始数组的该数组的副本。即:对副本进行修改也会修改原始副本。

private var original:ArrayCollection = new ArrayCollection();
...

private function doStuff()
{
    var modified:ArrayCollection = original;
    for each (var myObj:CustomObject in modified)
        ...
}

我所能得到的最接近的方法是使用ObjectUtil.Clone...

private var original:ArrayCollection = new ArrayCollection();
...

private function doStuff()
{
    var modified:ArrayCollection = ObjectUtil.clone(original);
    for each (var myObj:CustomObject in modified)
    {
        //Error here as the clone worked, however the objects in the array reverted to the base Object Class and couldn't be cast back to their actual CustomObject type
    }
}

下面是一个实用的示例:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               creationComplete="application1_creationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;

            private var originals:ArrayCollection;
            protected function application1_creationCompleteHandler(event:FlexEvent):void
            {
                originals = new ArrayCollection();
                for (var i:int = 0; i <= 5; i++)
                {
                    var myObj:CustomObject = new CustomObject();
                    originals.addItem(myObj);
                }
                doStuff();
            }

            private function doStuff():void
            {
                var modified:ArrayCollection = clone(originals);
                for (var i:int = 0; i < modified.length; i++)
                {
                    var myDupObj:CustomObject = modified[i] as CustomObject;
                    //do stuff
                    trace(myDupObj);
                }
            }

            private function clone(source:Object):*
            {
                var myBA:ByteArray = new ByteArray();
                myBA.writeObject(source);
                myBA.position = 0;
                return(myBA.readObject());
            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:Application>

和CustomObt.as

package
{
    public class CustomObject
    {
        public var a:String;
        public var b:String;
        public var c:String;

        public function CustomObject()
        {
            a = "Hello";
            b = "World";
            c = "Good-Bye";
        }
    }
}
vuv7lop3

vuv7lop31#

如果将[RemoteClass]元数据添加到CustomObject类,则ObjectUtil.clone(original)方法将起作用。

package
{
    [RemoteClass]
    public class CustomObject
    {
        public var a:String;
        public var b:String;
        public var c:String;
    }
}

这应该可以防止您在迭代克隆的集合时遇到强制转换错误。请记住,如果您的CustomObject具有任何其他“Custom”类型的属性,则这些类也将需要[RemoteClass]。

sauutmhj

sauutmhj2#

在进一步研究之后,我得出结论,这里使用的各种定制类可能过于复杂,无法使用通用实用程序完全复制。它们还用在应用程序的其他方面,与我试图修复的特定内容无关,所以我无法真正更改它们以使它们更容易工作。

我最终遍历了原始的arrayCollection,使用原始的属性创建了新的对象。即:

var modified:ArrayCollection = new ArrayCollection();
        for each (var myObject:CustomObject in original)
        {
            var newObject:CustomObject= new CustomObject();
                                    //... setup properties
            modified.addItem(newLayer);
        }
wwtsj6pe

wwtsj6pe3#

对象的变量,基本上是指向该对象的指针。所以,当你这样做的时候:

var modified:ArrayCollection = original;

原始是指向ArrayCollection的指针,该指针现在也存储在修改后的变量中。但是,它们仍然指向相同的ArrayCollection。

你说你试过克隆,但提到了它不起作用的事实--你没有详细说明为什么它不起作用。

要复制,可以使用ObjectUtil中的克隆或复制方法。我认为克隆执行了深度复制,这意味着引用的所有对象也会被复制,但复制不会复制引用的对象,所以这是一个“浅”复制。我可能颠倒了这一点。

我使用此方法复制一个项目中的ArrayCollection;我相信它是经过修改的ObjectUtil.Clone版本。

// clone method in ObjectUtils needs a UID; this one doesn't
public static function clone(source:Object):*
{
    var myBA:ByteArray = new ByteArray();
    myBA.writeObject(source);
    myBA.position = 0;
    return(myBA.readObject());
}
rqenqsqc

rqenqsqc4#

更改doStuff()函数,如下所示:-

private function doStuff():void
        {
            var modified:ArrayCollection = new ArrayCollection()
                modified.addAll(ObjectUtil.copy(originals.list) as IList);

            //following code only for testing 
            for (var i:int = 0; i < modified.length; i++)
            {
                modified[i].a = "Bye";
                trace(modified[i].a);
                trace(originals[i].a);
            }
        }

相关问题