我的应用使用字典
protected _categoryToValueDict:Dictionary = new Dictionary();
将某些东西映射到其他东西。
现在,在应用程序中的某个点,我需要从
Dictionary
中删除某个键。我实现了这个简单的方法:
public function setCategoryNoValue( cat:TAModelCategory ):void {
// delete( _categoryToValueDict[ cat ] );
var old:Dictionary = _categoryToValueDict;
_categoryToValueDict = new Dictionary();
for ( var key:* in old ) {
if ( key != cat ) {
_categoryToValueDict[ key ] = old[ key ];
}
}
}
如果我仅使用[delete运算符的说明]
delete( _categoryToValueDict[ cat ] );
该应用程序本身在正常模式下不会引发错误。但是,一旦我将其外部数据结构序列化为一个外部源[当前为SharedObject],应用程序就无法在其后反序列化。
如果我使用上面编码的手动迭代删除操作,则反序列化操作将按预期的方式起作用,并且该模型会出现在应用程序中。
备选方案应相同。不是吗
因此,我的问题是:这两种选择之间有什么区别?
PS:这个问题可能与my previous one有关。
UPDATE-1
Adobe在this page上进行了解释:
若要使myObject引用的对象有资格进行垃圾回收,必须删除对其的所有引用。在这种情况下,必须更改myObject的值并从myMap中删除myObject键,如以下代码所示:
myObject = null;
delete myMap[myObject];
假设这是一个错字。它不应该这样写:
delete myMap[myObject];
myObject = null;
为什么将null指针作为键传递给myMap?
最佳答案
好的,我花了大约两个小时的时间来研究这个问题,这比我打算花更多的时间研究这个问题要多得多。但是我很感兴趣。
我认为您可能已经发现ActionScript的AMF编码(或Dictionary
类如何通过AMF序列化)中的合法错误。该错误会影响使用AMF的所有错误,因此可以使用ByteArray
复制完全相同的错误,因此我将使用它进行演示。
考虑以下代码:
var d:Dictionary = new Dictionary(false);
d["goodbye"] = "world";
d["hello"] = "world";
delete d["hello"]
var ba:ByteArray = new ByteArray();
ba.writeObject(d);
var len:uint = ba.position;
ba.position = 0;
for(var i:uint=0;i<len;i++) {
trace(ba.readUnsignedByte().toString(16));
}
输出将是:
11 05 00 06 0f 67 6f 6f 64 62 79 65 06 0b 77 6f 72 6c 64
现在,如果我们从来没有将
"hello"
用作 key 怎么办: var d:Dictionary = new Dictionary(false);
d["goodbye"] = "world";
var ba:ByteArray = new ByteArray();
ba.writeObject(d);
var len:uint = ba.position;
ba.position = 0;
for(var i:uint=0;i<len;i++) {
trace(ba.readUnsignedByte().toString(16));
}
输出为:
11 03 00 06 0f 67 6f 6f 64 62 79 65 06 0b 77 6f 72 6c 64
请注意,长度是完全相同的,但是在第二个字节中它们是不同的。
现在让我们看一下如果不删除
"hello"
的序列化:11 05 01 06 0b 68 65 6c 6c 6f 06 0b 77 6f 72 6c 64 06 0f 67 6f 6f 64 62 79 65 06 02
请注意,第二个字节中的
05
与我们删除它时的相同。我认为这是指定词典中项目的数量。我之所以说“我认为”,是因为我花了相当长时间浏览AMF0/3的文档,试图弄清这里到底发生了什么,因为这似乎不应该是Dictionary的序列化,但是它相当一致,但我不明白。因此,我认为这就是为什么您遇到异常(特别是“文件末尾”错误)的原因,因为它仍然认为字典中应该有另一个项目需要反序列化。
您的备用方法之所以有效,是因为您正在构造一个新的Dictionary并将其填充...它的“内部计数器”一直在增加,因此它就像一种魅力。
还要注意的另一件事是,如果设置
d["Hello"] = undefined
,它不会引发异常,但是不会从字典中删除该项目。 key 在AMF流中被序列化为undefined
的值。因此,产生的字节流比没有字节流的情况更长。使用
Object
似乎没有表现出相同的行为。不仅不会产生错误,而且生成的字节码更符合我可以从Adobe找到的AMF0/3文档。从字面上看,结果“ key ”实际上已从序列化中删除,就像它从来没有出现过一样。因此,我不确定他们将Dictionary
(显然是未记录的AMF3数据类型0x11
)用于什么特殊情况,但是删除其中的项目并不能正常工作。对我来说,这似乎是个合法的错误。
编辑
所以我多挖了一点,发现其他人在谈论AMF serilization of a
Dictionary
。0x11 : Dictionary Data Type
0x05 : Bit code: XXXX XXXY
: If y == 0 then X is a reference to a previously encoded object in the stream
: If y == 1 then X is the number of key/val pairs in the dictionary.
因此,如果是这种情况
5&1 == 1
和5>>1 == 2
,那么它期望在“错误的”序列化版本中有两个键/值对。