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/

しかし、どれも機能していないようです。おそらく、iOSSDK用のAIR3.3では使用できません。(コンパイルされますが、私の場合はコードが機能しません)

他の方法はありますか、または誰かがAIR for iOSでオブジェクトのクローンを作成することを達成しましたか?

ありがとう、

できる。

4

2 に答える 2

1

クラスにプリミティブ値 (つまり、単純なデータ構造) のみが含まれている場合を除き、ActionScript ではビットごとの複製を行うことはできません。それが、この質問の回答ByteArrayでリンクしたアプローチが使用されているものです-しかし、複雑な型、特に表示オブジェクトを扱っている場合、すぐに限界に達します(私が収集したように、あなたはすでに気づいています) .

したがって、これには多かれ少なかれ2つのオプションがあります。

  1. 新しいオブジェクトを作成し、そのフィールドとプロパティをすべてコピーします。

    これは、ビヘイビアとフィールド値が必要で、描画方法を使用していない (つまり、この方法ではベクトル グラフィックスをコピーできない) 場合の方法です。正確な型を知らずに新しいクラス インスタンスを作成することは、リフレクションを使用して一般化された方法で行うことができ、getQualifiedClassName()そこでgetDefinitionByName()役立ちます。名前だけでなく、describeType(). ただし、これにも制限があります。privateフィールドは使用できません (フィールドは によって提供される情報には表示されませんdescribeType())。また、パフォーマンスの問題が発生しないようにするために、何らかのキャッシュを使用する必要があります。幸いなことに、as3commons-reflectはすでにこの問題を解決しているため、完全に機能する浅いコピー メカニズムに必要な残りの実装はそれほど複雑ではありません。

    次のように新しいインスタンスを作成します。

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

    次に、すべてのアクセサー、変数、および動的プロパティを反復処理し、古いインスタンスの値を割り当てます。

    私が取り組んでいるオープンソースフレームワークのために、私はこのような方法を自分で実装しました。githubでダウンロードまたはフォークできます。ドキュメントはまだありませんが、使い方は簡単です:

    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 に答える