Adobe Flex ActionScript предотвращает заражение модели - PullRequest
0 голосов
/ 29 марта 2011

У меня есть несколько магазинов значений в моей модели.Мне нужно создать копию этих значений, внести некоторые изменения, а затем вывести эти изменения, не затрагивая значения модели.

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 ]

1 голос
/ 29 марта 2011

Я упомянул, как это сделать в моем блоге , но краткий ответ - использовать ObjectUtil.copy (). То, что вы пытаетесь сделать, это не копирование, так как Flash использует объекты на основе ссылок, поэтому вы копируете только ссылку на другой массив. Используя ObjectUtil.copy (), вы делаете так называемую «глубокую копию», которая фактически воссоздает объект в новой ячейке памяти.

0 голосов
/ 29 марта 2011

Вы имеете дело со ссылками на данные, а не с копиями данных. Вот как работает 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
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...