Поиск…


Вступление

Ошибка 1009 - это общая ошибка, возникающая при попытке получить значение из переменной или свойства с null значением. Приведенные примеры вызывают различные случаи возникновения этой ошибки вместе с некоторыми рекомендациями по устранению ошибки.

замечания

Страшный и часто задаваемый вопрос «Ошибка 1009: невозможно получить доступ к свойству или методу ссылки на нулевой объект» - это сигнал о том, что некоторые данные отображаются нулевыми, но их пытаются использовать в качестве заселенного объекта. Есть довольно много типов проблем, которые могут вызвать это поведение, и каждый из них должен быть протестирован против кода, где возникла ошибка.

Этап недоступен

Иногда разработчики пишут код, который хочет получить доступ к stage , или к stage Flash, чтобы добавить слушателей. Он может работать в первый раз, а затем внезапно не работает и создает ошибку 1009. Этот код может быть даже на временной шкале, так как это первая инициатива по добавлению кода там, и многие учебники, которые все еще существуют, используют слот кода временной шкалы для размещения кода.

public class Main extends MovieClip {
    public function Main() {
        stage.addEventListener(Event.ENTER_FRAME,update); // here

Причина, по которой этот код не работает, прост: сначала создается экземпляр экранного объекта, затем добавляется в список отображения, а пока он не отображается в списке отображения, stage имеет значение null.

Хуже, если код выглядит следующим образом:

stage.addEventListener(Event.ENTER_FRAME,update); // here

размещается на временной шкале. Он может даже работать некоторое время, в то время как Main объект удаляется на сцену через графический интерфейс. Затем их SWF загружается из другого SWF, и внезапно код прерывается. Это происходит потому, что кадры Main создаются по-другому, когда SWF загружается непосредственно игроком и когда загрузка обрабатывается асинхронно. Решение состоит в том, чтобы использовать прослушиватель Event.ADDED_TO_STAGE и поместить весь код, который обращается к нему, и поместить сам прослушиватель в AS-файл вместо временной шкалы.

Недопустимый тип

function listener(e:Event):void {
    var m:MovieClip=e.target as MovieClip;
    m.x++;
}

Если такой прослушиватель прикреплен к объекту, который не является потомком MovieClip (например, Sprite ), то при неудачном провале будет проигнорировано, и любые последующие операции с его результатом будут вызывать ошибку 1009.

Неинтересный объект

var a:Object;
trace(a); // null
trace(a.b); // Error 1009

Здесь ссылка на объект объявляется, но никогда не назначается значение, будь то с new или присваиванием ненулевого значения. Запрос его свойств или метода приводит к ошибке 1009.

Многоуровневое выражение

x=anObject.aProperty.anotherProperty.getSomething().data;

Здесь любой объект до точки может оказаться нулевым, а использование методов, возвращающих сложные объекты, только увеличивает сложность для отладки нулевой ошибки. Худший случай, если метод подвержен посторонним отказам, скажем, получение данных по сети.

Результат необработанной функции

s=this.getChildByName("garbage");
if (s.parent==this) {...}

getChildByName() является одной из многих функций, которые могут возвращать значение null, если возникла ошибка при обработке его ввода. Поэтому, если вы получаете объект из любой функции, которая может возвращать значение null, сначала проверьте значение null. Здесь свойство немедленно запрашивается без предварительной проверки, если s равно null, это приведет к ошибке 1009.

Забытый слушатель событий

addEventListener(Event.ENTER_FRAME,moveChild);
function moveChild(e:Event):void {
    childMC.x++;
    if (childMC.x>1000) {
        gotoAndStop(2);
    }
}

В этом примере будет перемещен childMC (добавлен в Main во время разработки), но сразу же будет gotoAndStop() 1009, как только будет gotoAndStop() , если этот childMC не существует во фрейме 2. Основная причина этого заключается в том, что всякий раз, ключевой кадр (кадр, который не наследует набор объектов предыдущего кадра), либо с использованием gotoAndStop() , gotoAndPlay() с кадром назначения, отделенным от текущего кадра ключевым фреймом, либо обычным воспроизведением, если SWF является анимация, содержимое текущего кадра уничтожается, а новое содержимое создается с использованием данных, хранящихся в графическом интерфейсе. Таким образом, если новый кадр не имеет дочернего childMC именем childMC , запрос свойства возвращает null, а 1009 будет childMC .

Тот же принцип применяется, если вы добавляете двух слушателей событий, но удаляете только один или добавляете слушателя к одному объекту, но пытаетесь удалить из другого. removeEventListener не будет предупреждать вас, если объект не имеет соответствующего removeEventListener событий, поэтому прочитайте код, который добавляет и удаляет прослушиватели событий.

Также обратите внимание: использование объектов Timer вызове setInterval() и setTimeout() также создает прослушиватели событий, и они также должны быть очищены должным образом.

Недействительная ссылка на объект на основе кадра

Иногда gotoAndStop() вызывается в середине кода, который ссылается на некоторые свойства на основе кадра. Но сразу же после изменения рамки все ссылки на свойства, существующие в текущем фрейме, недействительны, поэтому любая обработка, которая их включает, должна быть немедленно прекращена.

Существует два общих сценария такой обработки: во-первых, цикл не заканчивается после gotoAndStop() , как здесь:

for each (bullet in bullets) {
    if (player.hitTestObject(bullet)) gotoAndStop("gameOver");
}

Здесь ошибка 1009 означает, что player MC был уничтожен во время обработки gotoAndStop() , но цикл продолжается и ссылается на ссылку now-null, чтобы получить hitTestObject() . Если условие скажет if (bullet.hitTestObject(player)) , ошибка будет # 2007 «Параметр hitTestObject не должен быть нулевым». Решение состоит в том, чтобы поставить оператор return сразу после вызова gotoAndStop() .

Второй случай - это несколько прослушивателей событий в одном и том же событии. Как это:

stage.addEventListener(Event.ENTER_FRAME,func1);
stage.addEventListener(Event.ENTER_FRAME,func2);
function func1(e:Event):void {
    if (condition()) {
        gotoAndStop(2);
    }
}

Здесь, если condition() истинно, первый прослушиватель выполнил бы gotoAndStop() , но второй слушатель все равно будет выполнен, и если он ссылается на объекты в кадре, будет вызвана ошибка 1009. Решение состоит в том, чтобы избежать нескольких прослушивателей в одном событии, в одном объекте, лучше иметь один прослушиватель, который обрабатывает все ситуации на этом событии и может нормально завершаться, если требуется изменение фрейма.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow