Статьи

Совет: как отладить ошибку AS3 # 1120

Очень распространенная ошибка ActionScript — ошибка 1120, ошибка «неопределенное свойство». Фактически, это может быть самой распространенной ошибкой во время компиляции. Его причина очень проста, но есть много способов, которыми это может быть вызвано. Мы кратко рассмотрим некоторые из сценариев, в которых вы столкнетесь с этой ошибкой, и способы их устранения.


Во-первых, давайте получим общее представление о том, что происходит с этой ошибкой. Это будет наша теоретическая дискуссия; мы перейдем к более практичным примерам в оставшейся части совета.

Эта ошибка возникает, когда вы ссылаетесь на переменную (или свойство) в строке кода, но эта переменная не существует. Если вы привыкли писать ActionScript на панели «Сценарий», а не в классах, не откладывайте термин «свойство». Я не буду подробно обсуждать, почему у нас есть эти два термина, но достаточно сказать, что, учитывая то, как ActionScript компилирует код из панели «Сценарий», переменная на самом деле является свойством.

Если компилятору ActionScript не удается найти указанное свойство, он помечает его как ошибку компилятора 1120. Вы увидите что-то вроде этого:

1
1120: Access of undefined property foo.

Где » foo » — это имя вашего оскорбительного имени.

Решить это обычно так же просто, как правильно назвать имя. Давайте взглянем.


Возьмите этот код для примера (если хотите, вы можете либо открыть « отсутствующий » пример проекта (то есть проект с именем «отсутствует» в исходной загрузке), либо создать этот проект самостоятельно: просто создайте новый файл Flash и класс документа для него, и поместите этот код в класс документа):

01
02
03
04
05
06
07
08
09
10
11
package {
    import flash.display.*;
    public class Missing extends Sprite {
 
        public function Missing() {
 
            foo = «Moo.»;
 
        }
    }
}

Скомпилируйте этот FLA, и вы получите 1120: Access of undefined property foo. ошибка, направленная на строку 7.

Опять же, причина, вероятно, очень ясна; вы никогда не объявляли свойство foo и поэтому используете его в строке 7 так, как если бы оно уже существовало, вызывает проблемы. Решение состоит в том, чтобы просто объявить переменную. Технически это может существовать где угодно в соответствующей области. Каждое из следующих решений является приемлемым:

Объявите это как параметр метода:

1
2
3
4
5
public function Missing(foo:String) {
 
    foo = «Moo.»;
 
}

Объявите его как локальную переменную внутри метода:

1
2
3
4
5
public function Missing() {
    var foo:String;
    foo = «Moo.»;
 
}

Объявите его как свойство экземпляра в классе:

01
02
03
04
05
06
07
08
09
10
11
12
13
package {
    import flash.display.*;
    public class Missing extends Sprite {
 
        private var foo:String;
 
        public function Missing() {
 
            foo = «Moo.»;
 
        }
    }
}

Решение зависит от того, что соответствует тому, что вы пытаетесь сделать. Нередко объявлять параметр метода, а затем просто устанавливать его в теле метода, хотя бывают случаи, когда вы хотите повлиять на значения параметров.

Что может быть интересно, так это способ, которым Flash будет искать переменную имени. Во-первых, он ищет локальную переменную с именем foo . Если он не был объявлен, он просматривает параметры для этого имени. Если он не может найти его там, он ищет свойство экземпляра с тем же именем. Если ничего из этого не найдено, вы увидите ошибку 1120.


Наш следующий пример будет довольно похожим. Опять же, вы можете просто открыть проект » опечатка » из загрузки; или создайте простой FLA с классом документа и вставьте / введите следующий код в класс; или просто читать вместе.

01
02
03
04
05
06
07
08
09
10
11
12
13
package {
    import flash.display.*;
    public class Typo extends Sprite {
 
        var foo:String;
 
        public function Typo() {
 
            boo = «Moo.»;
 
        }
    }
}

Здесь мало что происходит. Идея состоит в том, чтобы объявить свойство с именем foo , а затем в конструкторе установить для него значение "Moo." , Мясо этого находится в строках 5 и 9, выделенных выше. В остальном это просто шаблон класса документа.

Опять же, ошибка, вероятно, до боли очевидна. И, конечно, это так, когда есть только две строчки кода, о которых нужно заботиться. Очевидно, у нас есть опечатка; мы хотели написать:

1
foo = «Moo.»;

И если вы исправите опечатку, вы сможете скомпилировать FLA без ошибки 1120.

Хотя это очевидно, я хочу сделать две заметки. Во-первых, подобные опечатки на самом деле несколько распространены, и их сложнее вывести, когда в вашем проекте тысячи строк кода. Хорошая IDE или текстовый редактор могут помочь вам, предоставляя автозаполнение или другие виды проверки ошибок, но в качестве отказоустойчивого ActionScript также поможет вам, создав ошибку 1120.

Второе замечание: ошибка, о которой фактически сообщает ActionScript, заключается в том, что вы пытаетесь сослаться на свойство с именем « boo », но оно не находит его. В этом примере мы создали ошибку, введя опечатку в наш код. Но ActionScript не знает, что вы действительно имели в виду « foo »; он предполагает, что когда вы пишете » boo = "Moo."; «, что вы имели в виду boo , и предупреждает вас, когда он не может найти свойство с таким именем.

Это довольно тонкое различие, но полезно иметь в виду истинную причину ошибки.


Наш последний пример касается, в частности, Flash IDE, и его можно смело игнорировать, если вы не используете Flash CS3 / 4/5 и вместо этого используете Flash Builder с Flex Framework. Установка ошибки займет несколько простых шагов.

Вы можете найти проблемный проект в папке stage-instance пакета загрузки. Или вы можете воссоздать его, выполнив следующие действия:

  1. Начните с нового файла Flash и соответствующего класса документа.
  2. В файле Flash нарисуйте какую-нибудь фигуру и превратите ее в символ.
  3. Выберите экземпляр символа на сцене, откройте панель «Свойства» и назовите экземпляр instance_mc .
  4. Находясь во Flash, выберите « Файл»> «Параметры публикации», затем выберите вкладку « Flash ».
  5. Нажмите кнопку « Настройки…» рядом с всплывающим меню «Сценарий:».
  6. Где написано Stage: автоматически объявлять экземпляры stage , убедитесь, что флажок не установлен .
  7. Добавьте следующий код в класс документа:

    1
    2
    3
    4
    5
    6
    7
    8
    package {
        import flash.display.*;
        public class StageInstance extends Sprite {
            public function StageInstance() {
                instance_mc.rotation = 45;
            }
        }
    }

На данный момент, вперед и запустить фильм. Вы снова получите ошибку 1120.

Как вы можете догадаться, отключение «Автоматически объявлять экземпляры сцены» во многом было связано с генерацией ошибки. Это опция, которая по умолчанию включена, поэтому у вас, вероятно, есть причина для ее отключения.

Что делает, если довольно очевидно, но я добавлю свои два цента. Если у вас есть класс документа (или пользовательский класс, связанный с символом в библиотеке), этот класс расширяет Sprite или MovieClip . Типичные правила создания переменных и свойств применяются так же, как и любой другой класс, но поскольку у вас есть визуальный интерфейс к этому объекту — Flash IDE — вы можете неявно добавлять свойства, рисуя больше символов на сцене и присваивая им имена экземпляров. ,

Если включено «Автоматически объявлять экземпляры сцены», Flash будет проходить через объекты, добавленные на сцену через IDE, и вставлять объявления свойств в соответствующие классы для каждого экземпляра символа с именем.

Если он выключен, то Flash ничего не будет делать с экземплярами на сцене.

Чтобы избежать ошибки, вы можете просто включить эту опцию снова. Кроме того, вы можете вручную объявить экземпляры сцены. Если бы мы сделали наш класс документа похожим на это:

01
02
03
04
05
06
07
08
09
10
11
package {
    import flash.display.*;
    public class StageInstance extends Sprite {
 
        public var instance_mc:MovieClip;
 
        public function StageInstance() {
            instance_mc.rotation = 45;
        }
    }
}

Это также позволит избежать ошибки, потому что свойство все еще объявлено; Flash Professional не объявил его автоматически.

Обратите внимание, что если модификатор доступа не является public вы получите ошибку во время выполнения. Я не буду вдаваться в подробности этой ошибки; это будет для другого быстрого совета.

Теперь, почему вы вообще хотите отключить эту опцию? Я думаю, что все причины связаны с выходом за пределы Flash как инструмента разработки. Если вы используете Flash Builder для кодирования или ASDoc, или интегрируете содержимое Flash в проект Flex, вы можете оценить последствия отключения этой опции. Если вы отключите его, вы будете вынуждены объявить свойства вручную. Обратное также верно: если вы включите его, вы вынуждены не объявлять эти свойства вручную.

Таким образом, если вы запустите ваши файлы классов через ASDoc, он, скорее всего, найдет ссылку на экземпляр этапа, но не его объявление, и вы получите ошибку 1120. Включение этого параметра удобно, но его отключение заставляет вас написать более «чистый» код, более переносимый и автономный.


Как и многие ошибки, Ошибка 1120 проста в душе, и ее легко исправить, если вы знаете, что искать. Спасибо за чтение и следите за новыми советами по отладке!