Ste*_*eAp 11 apache-flex actionscript actionscript-3
我的应用程序使用字典
protected _categoryToValueDict:Dictionary = new Dictionary();
Run Code Online (Sandbox Code Playgroud)
将某事物映射到其他东西.
现在,在应用程序的某个点上,我需要删除某个键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 ];
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我只使用[ 删除运算符的描述]
delete( _categoryToValueDict[ cat ] );
Run Code Online (Sandbox Code Playgroud)
应用程序本身不会在正常模式下抛出错误.但是,只要我将其外部数据结构序列化为外部源[当前为SharedObject ],该应用程序就无法在以后对其进行反序列化.
如果我使用上面编码的手动迭代删除操作,反序列化操作按预期工作,模型出现在应用程序中.
替代方案应该是相同的.不应该吗?
因此,我的问题是:两种选择之间有什么区别?
PS:这个问题可能与我以前的问题有关.
UPDATE-1
Adobe在此页面上解释:
要使myObject引用的对象符合垃圾回收的条件,必须删除对它的所有引用.在这种情况下,您必须更改myObject的值并从myMap中删除myObject键,如以下代码所示:
myObject = null;
delete myMap[myObject];
Run Code Online (Sandbox Code Playgroud)
假设这是一个错字.不应该这样读:
delete myMap[myObject];
myObject = null;
Run Code Online (Sandbox Code Playgroud)
为什么将空指针作为键传递给myMap?
好吧,我只花了两个小时左右的时间来研究这个问题,这比我计划花钱看待这个要多得多.但我很好奇.
我想你可能在ActionScript的AMF编码中发现了一个合法的错误(或者Dictionary
通过AMF 如何通过AMF来分类).该bug会影响使用AMF的任何内容,因此完全相同的bug可以通过a重现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));
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
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));
}
Run Code Online (Sandbox Code Playgroud)
然后输出是:
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流中的值进行序列化.因此,生成的字节流比从未存在的字节流更长.
使用a Object
似乎没有表现出同样的行为.不仅不会产生错误,生成的字节码更符合我从Adobe找到的AMF0/3文档.由此产生的"密钥"实际上从序列化中删除,就像它实际上从未出现过一样.所以我不确定他们使用的是什么特殊情况Dictionary
(显然是未记录的AMF3数据类型0x11
),但它无法正确删除其中的项目.
这对我来说似乎是一个合法的错误.
编辑
所以我再挖了一下,发现其他人都在谈论AMF的血清化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.
Run Code Online (Sandbox Code Playgroud)
因此,如果这种情况下5&1 == 1
和5>>1 == 2
,所以它的预期的两个关键/缬氨酸对在"坏"的序列化版本.
归档时间: |
|
查看次数: |
3428 次 |
最近记录: |