0

我进行 AS3 Air 开发并使用 SQLite 在会话之间存储对象,这在AS3 Developer GuideAS3 SDK Reference中有详细记录。

存储在数据库中的类实现 IExternalizable,以便可以使用 BLOB 存储和恢复实例。这很有效,但我很难找到如何正确应对错误的反序列化。问题出现在以下情况:

  1. 对象序列化
  2. 对象已保存
  3. 班级改变和程序更新
  4. 序列化数据不再匹配保存的数据

我最初的方法是这样的:

public class SampleClass implements IExternalizable
{
    public static const version:int = 1; //increments upon program update
    public var idata:int;

    public function readExternal(data:IDataInput):void{
        if(version != data.readInt()) //check for corrupted data
            throw new IOError();

        idata = data.readInt();
    }

    public function writeExternal(data:IDataOutput):void{
        data.writeInt(version);
        data.writeInt(idata);
    }
}

可悲的是,在 readExternal 中抛出错误会导致我的 SQLStatement.execute() 严重失败,并且 try..catch 没有用。

我目前处理这个问题的想法:

  1. 程序更新时擦除数据库中的所有数据(哎哟)
  2. 向类添加标志以指示反序列化错误
  3. 使 SQLStatement.execute() 对抛出的错误做出正确反应

1和2我知道怎么做,但都不漂亮。3 我没有找到解决方案(还没有?)

其他想法或专业知识表示赞赏。

4

1 回答 1

2

嗨,这在 Adob​​e AIR 1.5 Cookbook(9.13 迁移 ActionScript 中的序列化更改)中有记录,由Greg Jastrab提供,他建议使用命名空间进行版本更改,如下面的代码示例:

public class WeatherData implements IExternalizable {
    namespace wd1_0 = "WD1.0";
    namespace wd1_1 = "WD1.1";

    protected var version:String;
    public var date:Date;
    public var low:Number;
    public var high:Number;

    public function WeatherData() {
        version = "WD1.1";
        date = new Date();
        low = high = 0;
    }
    public function readExternal(input:IDataInput):void {
        version = input.readUTF();
        var ns:Namespace = new Namespace(version);
        ns::parse(input);
    }
    public function writeExternal(output:IDataOutput):void {
        output.writeUTF(version);
        output.writeObject(date);
        output.writeFloat(low);
        output.writeFloat(high);
    }
    wd1_0 function parse(input:IDataInput):void {
        date = input.readObject() as Date;
        high = input.readFloat();
    }
    wd1_1 function parse(input:IDataInput):void {
        date = input.readObject() as Date;
        low = input.readFloat();
        high = input.readFloat();
    }
}

我已经使用了这个解决方案,它按承诺工作:) 以下是在未来版本中添加新成员的“算法”

  1. 添加新变量
  2. 修改 writeExternal 以将其包含在序列化中
  3. 在构造函数中增加版本字符串
  4. 为新版本添加新命名空间
  5. 添加一个作用域为新命名空间的解析函数并实现 readExternal 以匹配修改后的 writeExternal

此致

于 2013-01-03T09:09:16.270 回答