为什么 delete( DictionaryInstance[ key ] );失败? [英] Why does delete( DictionaryInstance[ key ] ); fail?

查看:21
本文介绍了为什么 delete( DictionaryInstance[ key ] );失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用使用字典

protected _categoryToValueDict:Dictionary = new Dictionary();

将某物映射到其他物.

现在,在应用程序的某个点,我需要从 Dictionary 中删除某个键.

Now, at a certain point in the application, I need to remove a certain key from the Dictionary.

我实现了这个简单的方法:

I implemented this simple method:

    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 的描述 运算符]

If I only use [description of the delete operator]

delete( _categoryToValueDict[ cat ] );

应用程序本身不会在正常模式下引发错误.但是一旦我将其外部数据结构序列化到外部源[目前SharedObject],应用以后无法对其进行反序列化.

the app itself doesn't throw errors in normal mode. But as soon as I serialize its external data structure to an external source [currently SharedObject], the app isn't able to de-serialize it later on.

如果我使用上面编码的手动迭代删除操作,反序列化操作按预期工作并且模型出现在应用中.

If I use the above coded manual iterative removal operation, the de-serialize operation works as expected and the model appears in the app.

替代方案应该是相同的.他们不应该吗?

The alternative should be identical. Shouldn't they?

因此,我的问题是:这两种选择有什么区别?

PS:这个问题可能有关我以前的.

UPDATE-1

Adobe 在此页面上进行了说明:

Adobe explains on this page:

要使 myObject 引用的对象有资格进行垃圾回收,您必须删除对它的所有引用.在这种情况下,您必须更改 myObject 的值并从 myMap 中删除 myObject 键,如下代码所示:

To make the object referenced by myObject eligible for garbage collection, you must remove all references to it. In this case, you must change the value of myObject and delete the myObject key from myMap, as shown in the following code:

myObject = null;
delete myMap[myObject];

<小时>

假设这是一个错字.不应该是这样的:


Is suppose this to be a typo. Shouldn't it read like this:

delete myMap[myObject];
myObject = null;

为什么将空指针作为键传递给 myMap?

Why pass a null-pointer to myMap as key?

推荐答案

好的,我只是花了两个小时左右的时间来研究这个,这比我计划花在这个上的要多得多.但我很感兴趣.

Okay, I just spent a good two hours or so looking into this, which is way more than I planning on spending looking at this. But I was intrigued.

我认为您可能已经发现了 ActionScript 的 AMF 编码(或者 Dictionary 类如何通过 AMF 序列化)中的一个合法错误.该错误会影响使用 AMF 的任何内容,因此完全相同的错误可以使用 ByteArray 重现,因此我将使用它进行演示.

I think you may have uncovered a legitimate bug in ActionScript's AMF encoding (or in how the Dictionary class gets seralized via AMF). The bug effects anything that uses AMF, so the exact same bug is reproduceable with a ByteArray, so I'm going to use that for demonstration purposes.

考虑以下代码:

        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" 作为键放入会怎样:

Now what if we don't ever put the "hello" in as a 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

请注意,长度完全相同,但它们的第二个字节不同.

Notice that the length is exactly the same, however they differ in the second byte.

现在让我们看看如果我不删除 "hello" 的序列化:

Now lets look at the serialization for if I don't delete "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 上的文档很长一段时间,试图弄清楚这里到底发生了什么,因为这似乎不应该是字典的序列化,但它相当一致,但我不明白.

Notice that 05 in the second byte is the same as when we deleted it. I think this is specifying the number of items in the Dictionary. I say "I think" because I dug through the documentation on AMF0/3 for quite a while trying to figure out exactly whats going on here, because it doesn't seem like this should be the serialization for a Dictionary, but its fairly consistent, but I don't get it.

所以我认为这就是您遇到异常(特别是文件结束"错误)的原因,因为它仍然认为字典中应该有另一个项目应该反序列化.

So I think that's why you are hitting an exception (specifically the "End of file" error), because its still thinks there should be another item in the dictionary that it should be de-serializing.

你的替代方法有效,因为你正在构建一个新的字典并填充它......它的内部计数器"只会不断增加,所以它就像一个魅力.

Your alternate method works because you are constructing a new Dictionary and populating it... Its "internal counter" is only ever increasing, so it works like a charm.

另一件要注意的事情,如果你设置了 d["Hello"] = undefined,它不会抛出异常,但该项目不会不会从词典.密钥在 AMF 流中使用 undefined 值进行序列化.因此,生成的字节流比从不存在时要长.

Another thing to note, that if you set d["Hello"] = undefined, it does not throw an exception, but the item does not get removed from the dictionary. The key gets serialized with a value of undefined in the AMF stream. So the resulting byte-stream is longer than if it was never there.

使用 Object 似乎没有表现出相同的行为.不仅不会产生错误,生成的字节码更符合我可以从 Adob​​e 找到的 AMF0/3 文档.由此产生的密钥"实际上从序列化中删除了,就像它实际上从未存在过一样.所以我不确定他们为 Dictionary 使用了什么特殊情况(显然是未记录的 AMF3 数据类型 0x11),但它不能正确地删除其中的项目.

Using an Object doesn't seem to exhibit this same behavior. Not only doesn't not produce an error, the generated bytecode is more in line with the AMF0/3 documentation I could find from Adobe. And the resulting "key" is literally dropped from the serialization, like it was in fact never there. So I'm not sure what special case they are using for Dictionary (apparently the undocumented AMF3 datatype 0x11), but it does not play right with deleting items out of it.

对我来说这似乎是一个合法的错误.

It seems like a legit bug to me.

编辑

所以我又挖了一些,发现其他人在谈论 Dictionary 的 AMF 序列化.

So I dug around a bit more and found other people talking about 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,那么它期望坏"中有两个键/值对连载版.

So if this case 5&1 == 1 and 5>>1 == 2, so it's expecting two key/val pairs in the "bad" serialized version.

这篇关于为什么 delete( DictionaryInstance[ key ] );失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆