Schnelltipp So debuggen Sie einen AS3-Fehler Nr. 1009

Eine der häufigsten Fragen, die ich in Foren sehe und von Kollegen bekomme, ist das Debuggen von Fehler 1009, der auch als Nullobjektreferenzfehler bezeichnet wird. Oder, wie ich es nenne, der ärgerliche Mosquito Error From Hell. Es tritt viel auf, und leider enthält der Fehler selbst nicht viel Informationen über die Fehlerquelle. In diesem kurzen Tipp werfen wir einen Blick auf einige Schritte, die Sie unternehmen können, um diese Stechmücke aufzuspüren und gut zu zerquetschen.


Einführung

Dieses Stück ist die erste Folge der allgemeineren Problembehebung in AS3. Tutorial. Wenn Sie einige der Techniken in diesem Tipp besser verstehen möchten, sollten Sie dies zunächst vollständig lesen.


Schritt 1: Verstehen Sie den Fehler

Es ist zu schade, dass Adobe keine weiteren Informationen über die Wurzel dieses Fehlers bereitstellt (oder kann). Vor allem ist es ziemlich offen formuliert (ähnlich wie alle ihre Fehler, aber dies mehr als die meisten):

TypeError: Fehler # 1009: Kein Zugriff auf eine Eigenschaft oder Methode einer NULL-Objektreferenz

Versuchen wir, dies in alltäglicher Hinsicht auszudrücken. Fehler 1009 bedeutet, dass Sie versucht haben, etwas mit einer Variablen zu tun, von der Sie annehmen, dass sie einen Wert hat, aber wirklich nicht. Flash mag das nicht. Sie würden es auch nicht mögen; Stellen Sie sich vor, Sie hätten ein Glas, von dem Sie annahmen, dass es mit dem leckeren Getränk Ihrer Wahl voll war, aber wirklich leer war. Sie packen das Glas und erwarten einen erfrischenden Schluck, aber Sie fühlen stattdessen das enttäuschende Gewicht eines leeren Glases. Das ist Ihr persönlicher Fehler 1009.

Wenn Sie dies in ActionScript tun:

 var s: String; trace (s.toUpperCase ());

Flash brennt hart (ein technischer Begriff für "Fehler erzeugen"), wenn Sie den Code ausführen. Die Variable s Möglicherweise wurde deklariert, aber sein Wert ist Null (wir setzen niemals den Wert, haben nur die Variable deklariert), also den Aufruf von toUpperCase Methode darauf ist mühsam.

Um klar zu sein, weil s wird als a deklariert String, das Compiler nimmt kein Problem mit dem Code auf: Es wird eine Variable aufgerufen s, es ist ein String, und toUpperCase ist eine gültige Methode zum Aufruf Strings. Der Fehler, den wir erhalten, ist a Laufzeit Fehler, was bedeutet, dass wir es nur erhalten, wenn wir die SWF-Datei ausführen. Erst wenn die Logik ausgeführt wird, können wir jetzt sehen, wie sich dies herausstellt.


Schritt 2: Debugging zulassen

Wie bei jedem Laufzeitfehler ist es manchmal ziemlich einfach, ohne zusätzliche Informationen den Vorgang zu erkennen. In anderen Fällen ist es hilfreich, dies weiter einzugrenzen. Aktivieren Sie an diesem Punkt "Debugging zulassen". Wenn diese Option aktiviert ist, erhalten Sie Fehler, die auch Zeilennummern enthalten. Alternativ können Sie in der Lage sein, Film zu debuggen. indem Sie die Tastenkombination Befehl-Umschalt-Zurück-Taste / Strg-Umschalt-Eingabe drücken.

Siehe dazu den allgemeinen Debugging-Tipps-Artikel? Beheben von Fehlern in AS3?

Manchmal reicht das aus. Wenn Sie die bestimmte Zeile kennen, können Sie alle Informationen benötigen, die Sie benötigen. Wenn nicht, werden wir im nächsten Schritt etwas tiefer graben.

Unser lieber Redakteur Michael James Williams hat den Punkt dieses Schrittes in einem Limerick zusammengefasst, den ich Ihnen jetzt mit seiner freundlichen Erlaubnis vorstellen möchte:

AS3-Fehler ein-oh-oh-neun
Ist nie ein sehr gutes Zeichen.
Kein Grund zur Besorgnis,
Drücken Sie Strg-Umschalttaste-Return
Und es wird die Ursache (naja, die Linie).


Schritt 3: Starten Sie die Verfolgung

Wenn Sie die fehlerhafte Zeile gefunden haben, sich aber noch nicht sicher sind, was los ist, wählen Sie die Zeile aus. Nehmen Sie jede Variable in dieser Zeile und verfolgen Sie sie vor der Fehler.

Da der Fehler beim Zugriff auf eine Eigenschaft oder beim Aufruf einer Methode für eine Nullvariable auftritt, sollten Sie zur Abdeckung Ihrer Basen alle Variablen und Eigenschaften verfolgen, auf die unmittelbar ein Punkt folgt. Nehmen Sie zum Beispiel diese Codezeile:

 myArray.push (someSprite.stage.align.toLowerCase ());

Zugegeben, das ist ein ziemlich erfundener Code, für den ich mir keine praktische Verwendung vorstellen kann, aber Sie sollten das herausfinden vier gesamt möglich Null Werte, auf die mit dem Punkt zugegriffen wird:

  • myArray: wir nennen das drücken Methode für diese Variable
  • SomeSprite: wir greifen auf die Bühne Eigentum
  • Bühne: wir greifen auf die ausrichten Eigentum
  • ausrichten: wir nennen das toLowerCase Methode

Ihr Debugging-Code könnte also folgendermaßen aussehen:

 trace ("meinArray:", meinArray); trace ("someSprite:", someSprite); trace ("someSprite.stage:", someSprite.stage); trace ("someSprite.stage.align:", someSprite.stage.align);

Ordnung ist wichtig; ob SomeSprite ist das Nullobjekt, aber Sie testen nach someSprite.stage.align vor dem Testen für SomeSprite, Sie haben weniger definitive Ergebnisse.

Nun spielt auch der gesunde Menschenverstand in diese Richtung. In meinem Beispiel, wenn Bühne existiert also ausrichten wird am sichersten einen Wert haben; das Bühne hat immer eine ausrichten Einstellung, auch wenn es der Standardwert ist.

Normalerweise sehen Sie Folgendes:

 myArray: [? Sachen im Array? someSprite: [object Sprite] someSprite.stage: null Fehler # 1009:? 

Was solltest du in dem der Bühne Eigentum ist Null, und jetzt können Sie es reparieren.


Schritt 4: Eine Lösung finden

Die einfachste Lösung besteht darin, die beleidigende Aussage in einem block und führe den Block nur aus, wenn die betreffende Variable nicht null ist. Angenommen, in unserem vorherigen Beispiel war dies tatsächlich der Fall Bühne das war Null, Wir könnten so etwas machen:

 if (someSprite.stage) myArray.push (someSprite.stage.align.toLowerCase ()); 

Dieser Test - if (someSprite.stage) - wird zurückkehren wahr wenn es einen Wert gibt (unabhängig vom Wert), und falsch wenn es Null. Im Allgemeinen funktioniert diese Notation; Sie können immer verwenden if (someSprite.stage! = null) wenn es dir lieber ist. NummerDie Situation ist jedoch etwas anders. Wenn die Nummer hat einen Wert von 0, dann hat es technisch einen wert, aber prüfend if (someNumberThatEqualsZero) wird zu bewerten falsch. Zum Nummers können Sie die verwenden isNaN () Funktion, um festzustellen, ob ein gültiger numerischer Wert in einer bestimmten Variablen gespeichert ist.

In jedem Fall ist diese Technik eine einfache Möglichkeit, den Fehler zu umgehen. Wenn die Variable, für die eine Operation ausgeführt werden soll, nicht festgelegt ist, führen Sie die Operation nicht aus. Wenn sich kein leckeres Getränk in unserem Glas befindet, heben Sie das Glas nicht auf. Einfach genug.

Dieser Ansatz ist jedoch nur möglich, wenn die Logik optional ist. Wenn die Logik erforderlich ist, können Sie der fraglichen Variablen vor der Fehleroperation möglicherweise einen Standardwert zuweisen. Zum Beispiel wenn myArray hat das Potenzial zu sein Null, Es ist jedoch unerlässlich, dass dies nicht der Fall ist. Wir können dies tun:

 if (! meinArray) meinArray = [];  myArray.push (someSprite.stage.align.toLowerCase ());

Zuerst wird geprüft, ob das Array vorhanden ist Null. Wenn ja, initialisieren Sie es mit einem leeren Array (ein leeres Array ist ein gültiger Wert. Er kann leer sein, aber es ist ein Array und nicht) Null), bevor die programmierte Codezeile ausgeführt wird. Wenn es nicht so ist Null, springen Sie direkt zur Codezeile. Wenn unser Glas leer ist, füllen Sie es mit einem leckeren Getränk, bevor Sie es abholen.

Darüber hinaus wenn myArray Ist eine Instanzeigenschaft der Klasse, in der diese Codezeile ausgeführt wird. Sie können einen gültigen Wert ziemlich sicher sicherstellen, indem Sie Ihre Eigenschaften bei der Initialisierung des Objekts initialisieren.

Was ist, wenn die Logik erforderlich ist, die fragliche Variable jedoch nicht so leicht unter unserer Kontrolle steht? Was ist beispielsweise, wenn unsere erfundene Codezeile erforderlich ist, die fragliche Variable jedoch SomeSprite.stage? Wir können das nicht einfach einstellen Bühne Eigentum; das wird intern gesteuert DisplayObject und ist für uns nur Sterbliche schreibgeschützt. Dann müssen Sie sich vielleicht schlau machen und den nächsten Schritt lesen.


Schritt 5: Umgang mit a Null Bühne

Es gibt wahrscheinlich unendlich viele Szenarien, in denen eine bestimmte Variable oder Eigenschaft vorhanden sein könnte Null. Natürlich kann ich nicht alle in einem Quick Tip behandeln. Es gibt jedoch eine bestimmte Situation, die immer wieder auftaucht.

Angenommen, Sie schreiben Code, der so aussieht:

 public class QuickSprite erweitert Sprite public function QuickSprite () stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove);  private Funktion onMove (e: MouseEvent): void var color: ColorTransform = neu ColorTransform (); color.color = stage.mouseX / stage.stageWidth * 0xFFFFFF; this.transform.colorTransform = Farbe; 

Ein weiteres Stück Code (der Anfälle auslösen könnte - betrachten Sie sich als gewarnt), aber im Grunde geht es darum, dass Sie einen haben Sprite Unterklasse und Sie legen dies als Klasse für einen Clip auf der Bühne fest, indem Sie die Flash-IDE verwenden.

Sie entscheiden jedoch, dass Sie mit diesen arbeiten möchten QuickSprites programmatisch. Also versuchst du das:

 var qs: QuickSprite = new QuickSprite (); addChild (qs);

Und Sie erhalten den verfluchten Fehler 1009. Warum? Weil in der QuickSprite Konstruktor greifen Sie auf die Bühne property (geerbt von DisplayObject). Wenn das Objekt vollständig mit Code erstellt wird, befindet es sich nicht an der Stelle, an der diese Codezeile ausgeführt wird Bühne ist Null und du bekommst den Fehler. Das QuickSprite wird die nächste Zeile hinzugefügt, aber es ist nicht früh genug. Wenn die Instanz erstellt wird, indem ein Symbol aus der Bibliothek auf die Bühne gezogen wird, wirkt hinter den Kulissen ein wenig Magie, die dafür sorgt, dass sich die Instanz auf der Bühne befindet Bühne Eigenschaft wird während des Konstruktors gesetzt.

Also, was Sie tun: Sie testen, ob ein Wert vorhanden ist Bühne. Je nach Ergebnis können Sie den Setup-Code entweder sofort ausführen oder einen anderen Ereignis-Listener für den Zeitpunkt einrichten QuickSprite wird der Bühne hinzugefügt. Etwas wie das:

 public function QuickSprite () if (stage) init ();  else this.addEventListener (Event.ADDED_TO_STAGE, init);  private Funktion init (e: Event = null) this.removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove); 

Wenn wir das bewegen Bühne Zeile zu einer anderen Funktion, und rufen Sie diese Funktion nur auf, wenn wir eine Stufe haben, dann sind wir eingestellt. Ob Bühne existiert von Anfang an, gehen Sie voran und laufen Sie drin() jetzt sofort. Wenn nicht, verwenden wir drin() als Event-Listener-Funktion für ADDED_TO_STAGE, An diesem Punkt haben wir einen Wert für die Stufe und können den Code ausführen. Jetzt können wir die Klasse für die Verbindung zu IDE Sprite oder vollständig programmgesteuert verwenden.

Dies funktioniert auch in Dokumentenklassen. Wenn Sie eine SWF-Datei selbst ausführen, hat die Dokumentenklasse sofortigen Zugriff auf diese Bühne. Wenn Sie diese SWF-Datei jedoch in eine andere SWF-Datei laden, wird der Code im Initialisierungsstapel der Dokumentklasse ausgeführt, bevor die geladene SWF-Datei der Anzeige hinzugefügt wird. Ein ähnliches Bühne-Wenn Sie den Trick überprüfen, können Sie mit der SWF-Datei sowohl als eigenständige als auch als SWF-Datei arbeiten, die in eine SWF-Datei geladen wird.


Das ist alles

Vielen Dank für das Lesen dieses Kurztipps! Ich hoffe, Sie werden ein wenig darüber aufgeklärt, wie Fehler 1009 auftritt und wie Sie ihn debuggen können. Bleiben Sie dran für weitere Schnelltipps zu anderen häufig auftretenden Fehlern.