2011-03-29 66 views
0

我在我的模型中有一些值存儲。我需要創建這些值的副本,進行一些更改,然後輸出這些更改而不影響模型值。Adob​​e 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數組會影響模型?我如何防止這種情況發生?

回答

1

我已經mentioned how to do this in my blog,但簡短的回答是使用ObjectUtil.copy() 。因爲Flash使用基於引用的對象,所以你只是在不復制,所以你只能將引用複製到另一個數組中。通過使用ObjectUtil.copy(),你正在做所謂的「深層複製」,它實際上是在新的內存位置重新創建對象。

+0

對於'ObjectUtil.copy()'+1。打敗我的串行器/解串器方法:) – 2011-03-30 01:59:41

+0

@布萊恩,這是一個好主意。你的序列化程序本質上就是ObjectUtil.copy所做的:) – 2011-03-30 14:24:19

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 
}