странное поведение в цикле Flex / as3 для каждого - PullRequest
2 голосов
/ 10 ноября 2010

Исходный код немного сложен, но сводится к следующему:

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.

И дружба не транзитивна . Что это, А не дружит с С.

По какой-то причине это напечатано:

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 ]

1 голос
/ 11 ноября 2010

Имея дело с такими странностями, есть несколько способов обнаружить, что не так.Первым и самым быстрым будет отладка с точкой останова перед проблемным фрагментом кода, а затем выполнение кода шаг за шагом.

Второй способ - удалить часть кода, либо создав новую свернутую версиютекущий код или комментируя часть кода.

Вот что я пробовал: Приложение:

<?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();
    }
}

Если вы запустите приложение, вы увидите, чтоон выполняется как ожидалось.Это означает, что вы делаете что-то еще в своем коде, что порождает итерацию в одном из циклов.

Так что, если вы не выясните, что в вашем коде нарушено, это было бы интересно (дляпо крайней мере мне), чтобы увидеть остальное.

0 голосов
/ 11 ноября 2010

Вы упоминаете, что это урезанная версия кода.

Делает ли действительный код какие-либо действия для изменения person.frinedArrayList.toArray()?

В двух версиях вашей версии есть небольшая разницаcode.

В последней версии, где вы используете переменную temp, значение person.friendArrayList.toArray() оценивается только один раз.

Однако в исходной версии person.friendArrayList.toArray() оценивается в начале каждого цикла цикла.Вполне возможно, что возвращаемое значение, поскольку оно зацикливается, вызывает поведение, которое вы видите.

Только по этой причине вторая версия предпочтительнее, так как она более производительная.Я подозреваю, что реальная проблема заключается в коде в цикле, и это влияет на результат вызова toArray ().

0 голосов
/ 11 ноября 2010

Оператор for each..in выполняет итерацию только по динамическим свойствам объекта, а не по фиксированным свойствам.Фиксированное свойство - это свойство, которое определяется как часть определения класса.Чтобы использовать оператор for each..in с экземпляром пользовательского класса, необходимо объявить класс с атрибутом dynamic.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...