我的应用使用字典

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 == 15>>1 == 2,那么它期望在“错误的”序列化版本中有两个键/值对。

09-15 21:58