我的应用程序使用字典
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运算符(operator)]
delete( _categoryToValueDict[ cat ] );
应用程序本身不会在正常模式下引发错误。但是只要我序列化 其外部数据结构到外部源 [当前 SharedObject ],应用程序无法反序列化 它稍后。
如果我使用上面的编码 手动迭代移除操作 ,反序列化操作 按预期工作 并且模型出现在应用程序中。
替代方案应该是相同的。他们不应该吗?
因此,我的问题是:这两种选择之间有什么区别?
PS:这个问题可能与my previous one有关.
更新-1
Adobe 在 this page 上解释:
要使 myObject 引用的对象有资格进行垃圾回收,您必须删除对它的所有引用。在这种情况下,您必须更改 myObject 的值并从 myMap 中删除 myObject 键,如以下代码所示:
myObject = null;
delete myMap[myObject];
假设这是一个错字。不应该是这样的:
delete myMap[myObject];
myObject = 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"
会怎样?作为关键: 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 上的文档很长一段时间,试图弄清楚这里到底发生了什么,因为这似乎不应该是字典的序列化,但它相当一致,但我不明白。所以我认为这就是为什么你会遇到异常(特别是“文件结束”错误),因为它仍然认为字典中应该有另一个项目应该反序列化。
你的替代方法有效,因为你正在构建一个新的字典并填充它......它的“内部计数器”只会不断增加,所以它就像一个魅力。
还有一点要注意,如果你设置
d["Hello"] = undefined
,它不会抛出异常,但该项目不会从字典中删除。键被序列化,值为 undefined
在 AMF 流中。因此,生成的字节流比它从不存在时要长。使用
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
,所以它期望在“坏”序列化版本中有两个键/值对。
关于actionscript-3 - 为什么 delete( DictionaryInstance[ key ] );失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7694075/