Szukaj…


Wprowadzenie

Błąd 1009 jest błędem ogólnym, który pojawia się, gdy próbujesz otrzymać wartość ze zmiennej lub właściwości o wartości null . Podane przykłady przedstawiają różne przypadki, w których pojawia się ten błąd, wraz z kilkoma zaleceniami dotyczącymi jego złagodzenia.

Uwagi

Przerażający i często pytany „Błąd 1009: nie można uzyskać dostępu do właściwości lub metody odwołania do zerowego obiektu” jest sygnałem, że niektóre dane wydają się puste, ale próbuje się go użyć jako zapełnionego obiektu. Istnieje wiele rodzajów problemów, które mogą powodować takie zachowanie, i każdy z nich powinien zostać przetestowany pod kątem kodu, w którym wystąpił błąd.

Scena jest niedostępna

Czasami programiści piszą kod, który chce uzyskać dostęp do stage lub etapu Flash, aby dodać detektory. Może działać po raz pierwszy, a potem nagle nie działa i generuje błąd 1009. Kod, o którym mowa, może nawet znajdować się na osi czasu, ponieważ jest to pierwsza inicjatywa dodania kodu i wiele istniejących samouczków używa warstwa kodu osi czasu, aby umieścić kod.

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

Przyczyna, dla której ten kod nie działa, jest prosta: najpierw wyświetlany jest obiekt wyświetlany, a następnie dodawany do listy wyświetlania, a gdy znajduje się poza listą wyświetlania, stage jest pusty.

Gorzej, jeśli kod taki jak ten:

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

jest umieszczony na osi czasu. Może nawet działać przez pewien czas, podczas gdy Main obiekt jest klapnięty na scenę za pośrednictwem GUI. Następnie ich plik SWF jest ładowany z innego pliku SWF i nagle kod pęka. Dzieje się tak, ponieważ ramki Main są konstruowane w inny sposób, gdy plik SWF jest ładowany bezpośrednio przez odtwarzacz i gdy ładowanie jest przetwarzane asynchronicznie. Rozwiązaniem jest użycie detektora Event.ADDED_TO_STAGE i umieszczenie w nim całego kodu, który dotyczy etapu, i umieszczenie samego detektora w pliku AS zamiast na osi czasu.

Niepoprawny typecast

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

Jeśli taki detektor zostanie dołączony do obiektu, który nie jest potomkiem MovieClip (na przykład Sprite ), rzut typu nie powiedzie się, a wszelkie dalsze operacje z jego wynikiem spowodują błąd 1009.

Nieinstantowany obiekt

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

W tym przypadku zadeklarowane jest odwołanie do obiektu, ale nigdy nie jest mu przypisywana wartość, zarówno new i przypisana wartość inna niż null. Żądanie jego właściwości lub metody powoduje błąd 1009.

Wielopoziomowa ekspresja

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

Tutaj każdy obiekt przed kropką może być pusty, a użycie metod zwracających złożone obiekty tylko zwiększa komplikację w celu debugowania błędu zerowego. Najgorszy przypadek, jeśli metoda jest podatna na zewnętrzne awarie, powiedzmy pobieranie danych przez sieć.

Wynik nieprzetworzonej funkcji

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

getChildByName() jest jedną z wielu funkcji, które mogą zwrócić wartość null, jeśli wystąpił błąd podczas przetwarzania danych wejściowych. Dlatego jeśli otrzymujesz obiekt z dowolnej funkcji, która może zwrócić wartość null, najpierw sprawdź, czy nie ma wartości null. Tutaj właściwość jest natychmiast sprawdzana bez uprzedniego sprawdzenia, czy s ma wartość null, spowoduje to wygenerowanie błędu 1009.

Zapomniany detektor zdarzeń

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

Ten przykład przeniesie childMC (dodany do Main w czasie projektowania), ale natychmiast wyrzuci 1009, gdy tylko zostanie wywołane gotoAndStop() , jeśli to childMC nie istnieje w ramce 2. Głównym powodem tego jest to, że za każdym razem, gdy przechodzi głowica klatka kluczowa (klatka, która nie dziedziczy zestawu obiektów poprzedniej klatki), albo za pomocą gotoAndStop() , gotoAndPlay() z ramką docelową oddzieloną od bieżącej klatki przez klatkę kluczową, lub przez normalne odtwarzanie, jeśli SWF jest animacja, zawartość bieżącej ramki jest niszczona, a nowa zawartość jest tworzona przy użyciu danych przechowywanych w GUI. Tak więc, jeśli nowa ramka nie ma elementu potomnego o nazwie childMC , żądanie właściwości zwróci null i zostanie wygenerowane 1009.

Ta sama zasada obowiązuje, jeśli dodasz dwa detektory zdarzeń, ale usuniesz tylko jeden lub dodasz detektor do jednego obiektu, ale spróbujesz usunąć z innego. Wywołanie removeEventListener nie ostrzega, jeśli do obiektu nie dołączono odpowiedniego detektora zdarzeń, dlatego należy uważnie przeczytać kod, który dodaje i usuwa detektory zdarzeń.

Uwaga: Używanie obiektów Timer , wywoływanie setInterval() i setTimeout() również tworzy detektory zdarzeń, które również powinny zostać poprawnie wyczyszczone.

Niepoprawne odwołanie do obiektu opartego na ramce

Czasami gotoAndStop() jest wywoływany w środku kodu, który odwołuje się do niektórych właściwości opartych na ramkach. Ale zaraz po zmianie ramki wszystkie łącza do właściwości, które istniały w bieżącej ramce, są unieważniane, więc wszelkie związane z nimi przetwarzanie należy natychmiast przerwać.

Istnieją dwa ogólne scenariusze takiego przetwarzania: Po pierwsze, pętla nie kończy się po gotoAndStop() , jak tutaj:

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

W tym przypadku błąd 1009 oznacza, że player MC został zniszczony podczas przetwarzania gotoAndStop() , ale pętla trwa i odwołuje się do pustego łącza do pobrania hitTestObject() . Gdyby warunek powiedziałby, if (bullet.hitTestObject(player)) zamiast tego if (bullet.hitTestObject(player)) , błąd wynosiłby # 2007 „Parametr hitTestObject nie może mieć wartości zerowej”. Rozwiązaniem jest umieszczenie instrukcji return zaraz po wywołaniu gotoAndStop() .

Drugi przypadek to detektory wielu zdarzeń tego samego zdarzenia. Lubię to:

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

Tutaj, jeśli condition() jest prawdziwy, pierwszy detektor gotoAndStop() , ale drugi detektor nadal byłby wykonany, a jeśli ten odwołuje się do obiektów w ramce, zostanie wygenerowany błąd 1009. Rozwiązaniem jest uniknięcie wielu detektorów na jednym zdarzeniu, w jednym obiekcie, lepiej mieć jeden detektor, który obsługuje wszystkie sytuacje na tym zdarzeniu i może poprawnie zakończyć, jeśli konieczna jest zmiana ramki.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow