ИСПРАВЛЕНО: Удаленное значение массива все еще отображается в цикле foreach в AS3 (ошибка во флэш-памяти?) - PullRequest
1 голос
/ 08 апреля 2010

ОБНОВЛЕНИЕ 2011.09.13 Эта ошибка была устранена Adobe.Пример кода ниже теперь демонстрирует правильное поведение.Оригинальный вопрос ниже.

Мне понадобилось много часов, чтобы сузить проблему в некотором коде до этой воспроизводимой ошибки, которая кажется мне ошибкой в ​​AVM2.Кто-нибудь может пролить свет на то, почему это происходит или как это исправить?

Когда значение по индексу 1 удаляется, а значение впоследствии устанавливается по индексу 0, несуществующее (неопределенное) значение по индексу 1теперь будет отображаться в цикле foreach.Я был в состоянии произвести этот результат только с индексами 1 и 0 (без каких-либо других n и n-1).

Запустите этот код:

package 
{
import flash.display.Sprite;
public class Main extends Sprite 
{
    public function Main():void 
    {
        var bar : Array = new Array(6);
        out(bar);

        //proper behavior
        trace("bar[1] = 1", bar[1] = 1);
        out(bar);

        //proper behavior
        trace("delete bar[1]", delete bar[1]);
        out(bar);

        //proper behavior
        trace("bar[4] = 4", bar[4] = 4);
        out(bar);

        //for each loop will now iterate over the undefined position at index 1
        trace("bar[0] = 0", bar[0] = 0);
        out(bar);

        trace("bar[3] = 3", bar[3] = 3);
        out(bar);
    }

    private function out(bar:Array):void
    {
        trace(bar);
        for each(var i : * in bar)
        {
            trace(i);
        }
    }
}

}

Это даст такой вывод:

,,,,,
bar[1] = 1 1
,1,,,,
1
delete bar[1] true
,,,,,
bar[4] = 4 4
,,,,4,
4
bar[0] = 0 0
0,,,,4,
0
undefined
4
bar[3] = 3 3
0,,,3,4,
0
undefined
4
3

РЕДАКТИРОВАТЬ: см. Ответ для вероятной причины ошибки.Невозможно найти исправление.Мое решение состояло в том, чтобы кодировать особый случай, когда, если установлен индекс 0, а индекс 1 не существует, удалить индекс 1 после установки индекса 0. Не совсем элегантное решение: \

Ответы [ 2 ]

1 голос
/ 08 апреля 2010

Похоже, вы сталкиваетесь с ошибкой, которая возникает, когда массивы AS3 разделяются на часть плотного массива и часть хеш-таблицы "rest".

Об этом сообщают в Adobe об ошибке «Базовый язык Actionscript»: FP-3477

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

Хотя ваш пример кода не вставляет один и тот же объект повторно, могут возникнуть проблемы, связанные с тем, как виртуальная машина оптимизирует буквенные числа нижнего диапазона (часто как общие, постоянные «объекты»)

0 голосов
/ 08 апреля 2010

Хотя это явно ошибка, я бы сказал, что это больше связано с тем фактом, что значения массива в какой-то форме странного состояния при инициализации как var bar : Array = new Array(6);, они должны быть повторены для начала, насколько яможно увидеть.

На самом деле я никогда не использую delete bar[1], чтобы избавиться от значения в массиве, я всегда обращаюсь к bar.splice(1, 1)*, когда при этом все неустановленные индексы начинают трассироваться как undefined, так чточто-то странное происходит.

Хотя я подозреваю, что вы на самом деле не ищете обходного пути, я просто попытался бы жить с потенциально повторяющимися пустыми позициями, либо обрабатывая их, когда вы сталкиваетесь с ними, либо вместо этого делая цикл типа for (var i:int = 0; i < bar.length; i++).

Если вам не нужно поведение типа массива, использование Object также может сработать, похоже, нет этой проблемы.

* это просто по предпочтению, без реальной причины.

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