IExternalizable(as3)

时间:2011-11-09 13:28:59

标签: actionscript-3 serialization interface deserialization iexternalizable

有没有人使用过IExternalizable界面? ...

我有一个基本问题。当我已经序列化我的对象...并保存为文件....现在我想在课堂上做一些改变......例如添加属性...我无法将文件重新转换为此类的对象...因为在readExternal方法中现在又有一个属性,即存储的对象(文件)不拥有....

有没有办法让这更灵活?

- //德语

Hallo hat schon mal jemand das imTitelerwähnteInterfacebenutzt? ...

Habe mal ne grundlegende Frage dazu。 Wenn ich mein Objekt serialisiert habe ... und als Datei abgespeichert habe .... und nun in der KlasseeinigeÄnderungenvornehmenmöchte... z.B。 einAttributhinzufügen... dann kann ich die Datei nicht wieder in ein Objekt dieser Klasse umwandeln ... weil in der readExternal methode nun ein属性mehr abgefragt wird,welches das gespeicherte Objekt(Datei)nicht besitzt ....

gibtsdaMöglichkeitendasflexibler zu machen?

2 个答案:

答案 0 :(得分:2)

您必须使用注册该类的别名 flash.net.registerClassAlias功能。这个东西添加了一些元数据(如果我是正确的)写入Amf对象,该对象允许Flash确定原始类。

然后将文件从文件系统或网络加载为ByteArray,并使用ByteArray#readObject()方法读取对象。

更多信息: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html

答案 1 :(得分:1)

如果您要在课程中添加,删除或更改属性,则这是一项不兼容的API更改。考虑一下你的类是否是其他开发人员已经使用过的软件库的一部分(例如你的同事,或者你的库是开源的,任何下载它并开始使用它的人开始使用它的人),如果你做了一个不兼容的这样改变,其他人的代码可能会立即停止工作或工作不正常。只允许在主要新版本之间进行此类API更改(例如,您的库版本为v1.X.Y,并且您发布了v2.0.0)。

当您将SomeClass的实例序列化为文件时,类名也存储在该文件中,因此当从文件中读回该实例时,Flash将知道要创建的类的实例。但是请注意,如果您更改API,它不再是相同的SomeClass,名称相同但类定义不同。没有简单的方法。

如果您确实需要访问该文件中的数据。一个简单的解决方案是将版本信息存储在数据文件中作为第一项。每次更改文件格式时,都应增加版本。编写文件时,首先编写当前版本。在读取文件时,读取当前版本并将其作为公共静态属性存储在可从项目中的任何位置访问的类中(例如,创建单独的类DataLoaderInfo和公共静态var formatVersion:String或uint)。然后像以前一样继续阅读文件。在您的类SomeClass中,您要修改它,如下所示:

function readExternal(input:IDataInput):void {

    // Read format version 0 properties.
    oldIntProperty1 = input.readInt();
    oldIntProperty2 = input.readInt();
    ...
    // Read format version 1 properties.
    if (DataLoaderInfo.formatVersion >= 1) {
        newIntProperty1 = input.readInt();
        ...
    }
    // Read format version 2 properties.
    if (DataLoaderInfo.formatVersion >= 2) {
        ...
    }
    ...
}

您可以想象,如果您有许多文件格式版本,代码可能会变得非常复杂。这完全取决于您正在开发的应用程序类型以及可能同时在该领域部署的版本数量。例如,如果您的应用是移动应用,将其设置或状态存储在二进制文件中,则每个用户可能会以不同的时间间隔进行更新,因此用户可能会从不同的旧版本升级到您的最新版本,因此您的应用应该能够优雅地加载所有这些版本的配置。如果您的所有数据都存储在您自己的服务器上,并且对该数据的唯一访问权限也是通过您服务器上部署的最新版本的应用程序,您只需要支持上次部署版本的格式和当前(新)版。

您也可以考虑制作一个单独的实用程序应用,将您的数据文件转换为更新的格式 1)创建原始类SomeClass的子类ExtSomeClass。将新API(例如属性)添加到子类。覆盖类的IExternalizable方法 - 首先调用super方法,然后读/写添加的新属性。
2)创建一个实用程序转换应用程序,读取包含SomeClass实例的原始文件。对于您阅读的每个SomeClass,您应该创建一个ExtSomeClass的新实例,复制所有SomeClass的属性并使用一些合理的默认值初始化ExtSomeClass属性。所以SomeClass的每个实例都被ExtSomeClass取代。将转换后的数据写回您的文件。 如果您不想创建子类,并且想要确实修改原始类SomeClass,您也可以这样做,但转换代码将更加棘手,因为您需要访问旧的和您的类的新版本,显然您不能在项目中编译两个具有相同名称的类,您必须将新的(更新的)类编译为单独的SWF,转换应用程序应使用旧版本编译在SomeClass中,您可以读取旧版本文件,使用旧版本的类可以正确读取SomeClass的每个实例。使用Loader加载包含新(更新)类的SWF,您可以使用loader.loaderInfo.applicationDomain.getDefinitionByName获取对新类的引用,您可以通过这种方式创建新类的实例,然后从实例复制所有属性你从文件中读到。