Adobe Flex ActionScript可防止模型污染

时间:2011-03-29 09:28:38

标签: flex actionscript

我的模型中有一些值存储。我需要创建这些值的副本,进行一些更改,然后输出这些更改,而不会影响模型值。

var my_source:Array = model.something.source
var output:Array = new Array();

for each (var vo:my_vo in my_source) {
    if (vo.id == 1) {
        vo.name = 'Foo';
        output.push(vo);
    }
    else if (vo.id == 21) {
        vo.name = 'Bar';
        output.push(vo);
    }
}
return output;

所以,这很好,除了循环通过my_source时所做的任何更改似乎也会影响model.something。为什么对my_source数组的更改会影响模型?我该如何防止这种情况发生?

2 个答案:

答案 0 :(得分:1)

mentioned how to do this in my blog,但简短的回答是使用ObjectUtil.copy()。您尝试做的是不复制,因为Flash使用基于参考的对象,因此您只是将引用复制到另一个数组。通过使用ObjectUtil.copy(),您正在执行所谓的“深层复制”,它实际上是在新的内存位置重新创建对象。

答案 1 :(得分:0)

您正在处理数据引用,而不是数据副本。这就是ActionScript-3(以及许多其他语言)的工作原理。

创建my_source变量时,您将创建对model.something.source的引用,该引用还包括对模型对象的所有引用。此外,当您遍历my_vo个对象时,您还会获得对这些对象的引用。这意味着如果您在此循环中对对象进行更改,则表示您正在更改模型中的对象。

你如何解决这个问题?在循环中,您需要复制对象。我不知道my_vo的样子,但是如果你在对象树中有任何其他对象,它们也会被引用,这可能需要“深层复制”来实现你想要的。

实现“深层复制”的最简单方法(但通常不是最有效的方法)是序列化和反序列化。实现这一目标的一种方法:

function deepCopy(source:Object):* {
    var serializer:ByteArray = new ByteArray();
    serializer.writeObject(source);
    serializer.position = 0;
    return serializer.readObject();
}

然后,在循环中,您可以复制数据:

for each(var vo:my_vo in my_source) {
    var copy:my_vo = deepCopy(vo);

    // act on copy instead of vo
}