Flex / as3 for-each循环中的奇怪行为

时间:2010-11-10 16:42:09

标签: flex actionscript-3

原始代码有点复杂,但归结为类似的东西:

for each (var person : Person in someArrayList.toArray())
{
    for each (var friend : Person in person.friendArrayList.toArray())
    {
        trace(person.name + " is friends with " + friend.name);
    }
}

有3个人:

  1. A是B的朋友
  2. B是C的朋友。
  3. 友谊不可传递。它,A不是C的朋友。

    出于某种原因,这打印的是:

    A is friends with B
    A is friends with C
    B is friends with C
    

    现在,如果我修改上面的代码以使用临时变量,那么打印输出是正确的。

    for each (var person : Person in someArrayList.toArray())
    {
        var friends : Array = person.friendArrayList.toArray(); // temp
        for each (var friend : Person in friends)
        {
            trace(person.name + " is friends with " + friend.name);
        }
    }
    
    
    A is friends with B
    B is friends with C
    

    这是设计的吗?我失去了理智吗?是什么给了什么?

3 个答案:

答案 0 :(得分:1)

在处理这样的奇怪事件时,有几种方法可以检测出错误。第一个也是最快的是在有问题的代码片段之前使用断点进行调试,然后逐步执行代码。

第二种方法是通过创建当前代码的新的最小化版本或通过注释某些代码来消除一些代码。

这是我尝试过的: 申请:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    creationComplete="onCreationComplete()"
    >
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import weird.Person;
            private function onCreationComplete() : void
            {
                var a : Person = new Person();
                a.name = "A";
                var b : Person = new Person();
                b.name = "B";
                var c : Person = new Person();
                c.name = "C";

                a.friendArrayList.addItem(b);
                b.friendArrayList.addItem(c);

                var someArrayList : ArrayCollection = new ArrayCollection([a,b,c]);

                for each (var person : Person in someArrayList.toArray())
                {
                    for each (var friend : Person in person.friendArrayList.toArray())
                    {
                        trace(person.name + " is friends with " + friend.name);
                    }
                }
            }
        ]]>
    </mx:Script>
</mx:Application>

Person类:

package weird
{
    import mx.collections.ArrayCollection;

    public class Person
    {
        public var name : String = null;
        public var friendArrayList : ArrayCollection = new ArrayCollection();
    }
}

如果您运行该应用程序,您将看到它按预期执行。这意味着你在代码中做了其他事情,搞砸了其中一个循环中的迭代。

因此,如果您没有弄清楚代码中的内容是什么,那么(至少对我而言)看到剩下的内容会很有趣。

答案 1 :(得分:0)

for each..in语句只迭代对象的动态属性,而不是固定属性。固定属性是定义为类定义的一部分的属性。要将for each..in语句与用户定义的类的实例一起使用,必须使用dynamic属性声明该类。

答案 2 :(得分:0)

你提到这是代码的精简版本。

实际代码是否可以修改person.frinedArrayList.toArray()?

您的代码的两个版本存在细微差别。

在使用temp变量的后一版本中,person.friendArrayList.toArray()的值仅评估一次。

但是,在原始版本中,person.friendArrayList.toArray()在循环的每个循环开始时进行评估。返回值可能与循环不同,导致您看到的行为。

仅凭这个原因,第二个版本更可取,因为它更具性能。

但是,我怀疑真正的问题在于循环中的代码,并且它会影响toArray()调用的结果。