2

我正在用 Flash 编写 iOS 游戏,我需要一种克隆多态对象的方法。我有 BaseClass、SubClass1、SubClass2(等等......),我需要 BaseClass 中的 clone() 方法,它将创建当前对象的副本,没有条件,例如

var obj:BaseClass;
if(this is SubClass1) { 
   obj = new SubClass1(); 
}else if(this is SubClass2) {
   obj = new SubClass2();
}else...

我需要一种方法来创建对象并创建对象的确切字节(是的,浅拷贝就足够了)。我看过:

AS3 - 克隆一个对象

As3 复制对象

http://actionscripthowto.com/how-to-clone-objects-in-as3/

但似乎没有一个工作。AIR 3.3 for iOS SDK 中可能不可用。(他们编译,但代码在我的情况下不起作用)

有没有其他方法,或者有没有人实现在 AIR for iOS 中克隆一个对象?

谢谢,

能。

4

2 回答 2

1

使用 ActionScript 无法进行逐位克隆,除非您的类仅包含原始值(即简单的数据结构)。这就是ByteArray您在这个问题的答案中链接到的方法的用途 - 但是当您处理复杂类型,尤其是显示对象时,您很快就会达到极限(据我所知,您已经意识到) .

所以这或多或少给你留下了两个选择:

  1. 创建一个新对象并复制其所有字段和属性。

    如果您需要行为和字段值,并且您没有使用任何绘图方法(即,您不能以这种方式复制矢量图形),这就是您要走的路。在不知道其确切类型的情况下创建一个新的类实例可以使用反射以一种通用的方式完成,getQualifiedClassName()并且getDefinitionByName()会在这方面为您提供帮助,如果您需要的不仅仅是名称,describeType(). 但是,这也有限制:private字段将不可用(它们不会出现在 提供的信息中describeType()),并且为了不遇到性能问题,您将不得不使用某种缓存。幸运的是,as3commons-reflect已经解决了这个问题,因此实现功能齐全的浅拷贝机制所需的其余部分并不太复杂。

    像这样创建一个新实例:

    var newObject:* = new Type.forInstance( myObject ).clazz();
    

    然后遍历所有访问器、变量和动态属性并分配旧实例的值。

    我自己已经为我正在开发的开源框架实现了这样的方法。您可以在github下载或 fork 。目前还没有任何文档,但它的使用就像编写一样简单:

    var myCopy:* = shallowCopy( myObject );
    

    我也有一个copy()方法,它可以创建一个真正的深层副本。但是,除了数据结构(尽管很大)之外,还没有对其他任何东西进行过测试,因此使用风险自负;)

  2. 创建位图副本。

    如果您确实有矢量图形,这通常比重新创建图像更容易:只需将对象的内容绘制graphics到新的位图。

    function bitmapCopy( source:Sprite ):Bitmap {
        source.cacheAsBitmap = true;
        var bitmapData:BitmapData = new BitmapData( source.width, source.height, true, 0xFFFFFF );
        bitmapData.draw( source, new Matrix(), null, null, null, true );
    
        return new Bitmap( bitmapData, PixelSnapping.AUTO, true );
    }
    
于 2012-07-22T14:32:18.337 回答
0

您需要clone在基类中创建一个抽象方法并为每个子类实现它。在具体实现中,您会将对象的所有属性复制到新的对象中。

public class BaseClass {
    public function clone():BaseClass
    {
         // throw an error so you quickly see the places where you forgot to override it
         throw new Error("clone() should be overridden in subclasses!");
         return null;
    }
}

public class Subclass1 extends BaseClass {
    public override function clone():BaseClass
    {
         var copy:Subclass1 = new Subclass1();
         copy.prop1 = prop1;
         copy.prop2 = prop2;
         // .. etc
         return copy;
    }
}

如果你想创建一个通用的默认实现clone,你可以describeType用来访问属性并将它们复制过来:

public function clone():BaseClass
{
    var defn:XML = describeType(this);
    var clsName:String = defn.@name;
    var cls:Class = getDefinitionByName(clsName) as Class;
    var inst:* = new cls();
    for each(var prop:String in (defn.variable + defn.accessor.(@access == 'readwrite')).@name )
    {
        inst[prop] = this[prop];
    }
    return inst;
}

这样做的主要问题是 describeType XML 可能会变得非常大,尤其是在处理扩展对象时DisplayObject。这可能会使用大量内存并且在 iOS 上速度很慢。

于 2012-07-22T10:48:21.473 回答