Actionscript 3 如何在不知道iOS在空中的确切类型的情况下克隆对象
我正在用Flash编写一个iOS游戏,我需要一种克隆多态对象的方法。 我有基类、子类1、子类2(等等),我需要基类中的clone()方法,该方法将创建当前对象的副本,,而不带条件,例如Actionscript 3 如何在不知道iOS在空中的确切类型的情况下克隆对象,actionscript-3,air,Actionscript 3,Air,我正在用Flash编写一个iOS游戏,我需要一种克隆多态对象的方法。 我有基类、子类1、子类2(等等),我需要基类中的clone()方法,该方法将创建当前对象的副本,,而不带条件,例如 var obj:BaseClass; if(this is SubClass1) { obj = new SubClass1(); }else if(this is SubClass2) { obj = new SubClass2(); }else... 我需要一种方法来创建一个对象并创建对象的
var obj:BaseClass;
if(this is SubClass1) {
obj = new SubClass1();
}else if(this is SubClass2) {
obj = new SubClass2();
}else...
我需要一种方法来创建一个对象并创建对象的精确字节(是的,一个浅拷贝就足够了)。我看过:
但似乎都不管用。对于iOS SDK,AIR 3.3可能不可用。(它们可以编译,但代码在我的情况下不起作用)
有没有其他方法,或者有没有人在iOS上实现了在空中克隆一个对象
谢谢
Can.您需要在基类中创建一个抽象的
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;
}
这方面的主要问题是DescripteType XML可能会变得相当大,尤其是在处理扩展了
DisplayObject
的对象时。这可能会占用大量内存,并且在iOS上速度较慢。不能使用ActionScript进行逐位克隆,除非您的类只包含基本值(即简单的数据结构)。这就是您在中链接到的ByteArray
方法的用途-但是当您处理复杂类型,尤其是显示对象时,您很快就会达到极限(据我所知,您已经意识到)
因此,这或多或少给您留下了两个选择:
getQualifiedClassName()
和getDefinitionByName()
将在这方面帮助您,如果您需要的不仅仅是名称,describeType()
。不过,这也有限制:private
字段将不可用(它们不会出现在describeType()
提供的信息中),并且为了不出现性能问题,您必须使用某种缓存。幸运的是,我们已经解决了这个问题,所以实现一个功能齐全的浅层复制机制所需的其余部分并不太复杂
创建一个新实例,如下所示:
var newObject:* = new Type.forInstance( myObject ).clazz();
然后迭代所有访问器、变量和动态属性,并分配旧实例的值
我自己也实现了这样一种方法,用于我正在开发的开源框架。您可以下载或在。目前还没有任何文档,但它的使用非常简单:
var myCopy:* = shallowCopy( myObject );
我还有一个copy()
方法,它创建了一个真正的深度副本。但是,除了数据结构(尽管是大型结构)之外,还没有对其进行测试,因此使用风险自负;)图形的内容绘制到新位图
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 );
}
有几种方法可以做到这一点,但首先请解释为什么需要将其限制在基类中-似乎最明显的选择是为每个子类型重写clone()方法,并手动复制所有字段。我不需要在子类中做任何额外的事,因为子类中会有很多字段。因此,复制位的clone()方法就足够了。如果我需要在任何子类的clone方法中添加任何内容,我只需要重写它并添加行为。不,这显然不是我想要的。我需要一个通用的默认实现,它将通过查看对象的当前类型在内存中实际创建对象。(无条件)如var newobj:BaseClass=createBitByBitExactCopy(derivedClassInstance);我不知道派生实例的确切类型。我只知道它是基类的一个派生类。你们不能访问内存中的对象。如果您想创建一个通用克隆,可以执行类似于我在编辑中添加的操作。否则,您可以使用
ByteArray.writeObject()
,但您仍然需要做一些额外的工作,而且它不会复制内存。ByteArray.writeObject实际上正是我想要的,但我似乎无法让它在AIR 3.3 for iOS上运行。我很高兴使用(并测试)您的库。但是这个项目将商业化(我计划在App Store中以一两美元的价格出售这个游戏),在我的项目中使用你的库会导致许可证问题吗?不会。这是一个非常早期的阶段,我还没有添加任何许可证信息,但它将在麻省理工学院的许可证下。我希望你能给我一点荣誉感,但这当然不是要求。我用过你的图书馆。它非常容易使用,并且能够创建相同类型的新对象。但是,它没有将任何属性从旧对象复制到新对象。它只是创建了一个相同类型的新实例(我一开始就试图实现),但没有一个字段被复制到新对象中。我真的不知道如何将某些内容放到github中,但这里是我仅有的代码:StandardSmileys从中派生(目前没有添加任何内容)(作为带有AS3导出选项的Flash中设计的MovieClip),我使用的代码是copySmiley函数(smi:Smiley):Smiley{var newsmi:Smiley=shallowCopy(smi);return newsmi;}好的,我看到您没有使用AS3的访问器约定-getField()
和setField()
将无法识别