Una delle domande più comuni che vedo sui forum e dai colleghi è come eseguire il debug dell'errore 1009, noto anche come "Errore di riferimento agli oggetti Null". O, come lo chiamo, il? Fastidioso Mosquito Error From Hell.? Sorge molto, e sfortunatamente l'errore in sé non contiene molte informazioni sulla fonte dell'errore. In questo suggerimento, daremo un'occhiata ad alcuni passi che puoi seguire per rintracciare questa zanzara e schiacciarla.
Questo pezzo è il primo seguito ai più generali bug di riparazione in AS3? tutorial. Se desideri comprendere meglio alcune delle tecniche di questo suggerimento, potresti prima leggerlo per intero.
Peccato che Adobe non (o non possa) fornire ulteriori informazioni sulla radice di questo errore. Prima di tutto, è piuttosto formulata in modo ottusamente (molto simile a tutti i loro errori, ma questo più della maggior parte):
TypeError: Errore # 1009: impossibile accedere a una proprietà oa un metodo di riferimento a un oggetto nullo
Proviamo a metterlo in termini quotidiani. L'errore 1009 significa che hai provato a fare qualcosa con una variabile che presumi abbia un valore, ma in realtà non lo fa. A Flash non piace. Non ti piacerebbe neanche; Immagina di avere un bicchiere che hai immaginato fosse pieno della bevanda gustosa di tua scelta, ma in realtà era vuoto. Prendi il bicchiere, aspettandoti un sorso rinfrescante, ma senti invece il peso deludente di un bicchiere vuoto. Questo è il tuo errore personale 1009.
In ActionScript, se si esegue questa operazione:
var s: String; trace (s.toUpperCase ());
Flash si romperà duramente (un termine tecnico per? Produrre un errore?) Quando si esegue il codice. La variabile S
potrebbe essere stato dichiarato, ma il suo valore è nullo
(non impostiamo mai il valore, abbiamo appena dichiarato la variabile), quindi chiamiamo il toUpperCase
il metodo su di esso è problematico.
Per essere chiari, perché S
è dichiarato come a Stringa
, il compilatore non prende alcun problema con il codice: c'è una variabile chiamata S
, è un Stringa
, e toUpperCase
è un metodo valido per chiamare Stringa
S. L'errore che otteniamo è a run-time errore, il che significa che lo otteniamo solo quando eseguiamo il file SWF. Solo quando viene eseguita la logica, ora vediamo come questo si rivela.
Come con qualsiasi errore di run-time, a volte è abbastanza facile dire cosa sta succedendo senza ulteriori informazioni. Ma altre volte è utile restringere ulteriormente questo aspetto. A questo punto, prova ad attivare? Permettere il debug.? Quando è abilitato, ricevi degli errori che ti danno anche dei numeri di linea. In alternativa, potresti riuscire a "Debugare film"? premendo Comando-Maiusc-Ritorna / Controllo-Maiusc-Invio.
Per fare ciò, consultare l'articolo generale sui suggerimenti per il debug, "Correggere i bug in AS3?
A volte questo è abbastanza. Conoscere la linea specifica potrebbe essere tutte le informazioni necessarie. Altrimenti, scaveremo un po 'più in profondità nel prossimo passo.
Il nostro caro editor, Michael James Williams, ha riassunto il punto di questo passaggio in un limerick, che sono felice di presentarvi ora con il suo gentile permesso:
Errore AS3 one-oh-oh-nine
Non è mai un buon segno.
Non c'è motivo di preoccuparsi,
Premi Ctrl-Maiusc + Invio
E individuerà la causa (beh, la linea).
Se hai individuato la linea incriminata ma non sai ancora cosa sta succedendo, scegli la linea. Prendi tutte le variabili in quella linea e tracciarle precedente a l'errore.
Poiché l'errore si verifica quando si accede a una proprietà o si chiama un metodo su una variabile nulla, per coprire le basi si devono tracciare tutte le variabili e le proprietà immediatamente seguite da un punto. Ad esempio, prendi questa riga di codice:
myArray.push (someSprite.stage.align.toLowerCase ());
Certo, è un pezzo di codice piuttosto inventato che non riesco a immaginare per un uso pratico, ma dovresti identificarlo quattro totale possibile nullo
valori a cui si accede con il punto:
myArray
: stiamo chiamando il Spingere
metodo su questa variabilesomeSprite
: stiamo accedendo al palcoscenico
proprietàpalcoscenico
: stiamo accedendo al allineare
proprietàallineare
: stiamo chiamando il toLowerCase
metodoQuindi il tuo codice di debug potrebbe essere simile a questo:
trace ("myArray:", myArray); trace ("someSprite:", someSprite); trace ("someSprite.stage:", someSprite.stage); trace ("someSprite.stage.align:", someSprite.stage.align);
L'ordine è importante; Se someSprite
è l'oggetto nullo, ma si prova per someSprite.stage.align
prima di provare per someSprite
, si finisce con risultati meno definitivi.
Ora, anche il buon senso gioca su questo. Nel mio esempio, se palcoscenico
esiste, quindi allineare
avrà sicuramente un valore; il Palcoscenico
ha sempre un allineare
impostazione, anche se è il valore predefinito.
In genere, vedrai qualcosa di simile al seguente:
myArray: [? roba nell'array? ] someSprite: [object Sprite] someSprite.stage: null Errore # 1009:?
Quale dovrebbe indurvi in quello il palcoscenico
la proprietà è nullo
, e ora puoi andare a ripararlo.
La soluzione più semplice è quella di concludere la frase incriminata in un? If? blocco, e solo eseguire il blocco se la variabile in questione non è nullo. Quindi, supponendo che nel nostro esempio precedente, fosse in effetti palcoscenico
quello era nullo
, potremmo fare qualcosa del genere:
if (someSprite.stage) myArray.push (someSprite.stage.align.toLowerCase ());
Questo test - se (someSprite.stage)
- tornerà vero
se c'è un valore (indipendentemente dal valore), e falso
se è nullo
. In generale questa notazione funziona; puoi sempre usare if (someSprite.stage! = null)
se preferisci. Numero
s presentare una situazione leggermente diversa, però. Se la Numero
ha un valore di 0
, quindi tecnicamente ha un valore, ma prova se (someNumberThatEqualsZero)
valuterà a falso
. Per Numero
s puoi usare il isNaN ()
funzione per determinare se un valore numerico valido è memorizzato in una determinata variabile.
Ad ogni modo, questa tecnica è un modo semplice per eludere l'errore. Se la variabile su cui vogliamo eseguire un'operazione non è impostata, non eseguire l'operazione. Se non ci sono bevande gustose nel nostro bicchiere, non raccogliere il bicchiere. Abbastanza semplice.
Ma questo approccio è possibile solo se la logica è opzionale. Se è necessaria la logica, allora è possibile fornire un valore predefinito alla variabile discutibile prima dell'operazione di errore. Ad esempio, se myArray
ha il potenziale per essere nullo
, ma è imperativo che non lo sia, possiamo farlo:
if (! myArray) myArray = []; myArray.push (someSprite.stage.align.toLowerCase ());
Questo prima controllerà per vedere se l'array è nullo
. Se lo è, inizializza su una matrice vuota (una matrice vuota è un valore valido. Può essere vuota, ma è una matrice, e non nullo
) prima di eseguire la linea di codice forzata. Se non lo è nullo
, salta direttamente alla linea di codice inventata. In termini reali, se il nostro bicchiere è vuoto, riempilo con una bevanda gustosa prima di prenderlo.
Inoltre, se myArray
è una proprietà di istanza della classe in cui è in esecuzione questa riga di codice, è possibile garantire in modo sicuro un valore valido inizializzando le proprietà quando l'oggetto viene inizializzato.
Cosa succede se la logica è richiesta, ma la variabile in questione non è così prontamente sotto il nostro controllo? Ad esempio, cosa succede se la nostra linea di codice inventata è richiesta, ma la variabile discutibile è someSprite.stage
? Non possiamo semplicemente impostare il palcoscenico
proprietà; che è controllato internamente a DisplayObject
ed è di sola lettura per noi comuni mortali. Quindi potresti aver bisogno di essere furbo e leggere il passaggio successivo.
nullo
palcoscenicoCi sono probabilmente un numero infinito di scenari in cui una determinata variabile o proprietà potrebbe essere nullo
. Ovviamente, non posso coprirli tutti in un Suggerimento rapido. C'è una situazione specifica, tuttavia, che ricorre continuamente.
Diciamo che scrivi un codice simile a questo:
public class QuickSprite estende Sprite public function QuickSprite () stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove); funzione privata onMove (e: MouseEvent): void var color: ColorTransform = new ColorTransform (); color.color = stage.mouseX / stage.stageWidth * 0xFFFFFF; this.transform.colorTransform = color;
Un altro pezzo di codice inventato (che potrebbe indurre crisi epilettiche - considera te stesso avvisato), ma in fondo l'idea è che tu abbia un folletto
sottoclasse e lo imposti come classe per una clip sullo stage, utilizzando l'IDE Flash.
Tuttavia, decidi di voler lavorare con questi QuickSprite
s a livello di programmazione. Quindi provi questo:
var q: QuickSprite = new QuickSprite (); addChild (qb);
E ottieni l'errore 1009 maledetto. Perché? Perché nel QuickSprite
costruttore, si accede al palcoscenico
proprietà (ereditata da DisplayObject
). Quando l'oggetto viene creato interamente con il codice, non è sul palco nel punto in cui quella linea di codice viene eseguita, ovvero palcoscenico
è nullo
e ottieni l'errore Il QuickSprite
viene aggiunta la riga successiva, ma non è abbastanza presto. Se l'istanza viene creata trascinando un simbolo fuori dalla libreria e sul palco, c'è un po 'di magia al lavoro dietro le quinte che assicura che l'istanza sia sul palco (cioè, il palcoscenico
proprietà è impostata) durante il costruttore.
Quindi, ecco cosa si fa: si prova per l'esistenza di un valore per palcoscenico
. A seconda del risultato, è possibile eseguire immediatamente il codice di configurazione o impostare un listener di eventi diverso per quando il file QuickSprite
viene aggiunto al palco. Qualcosa come questo:
funzione pubblica QuickSprite () if (stage) init (); else this.addEventListener (Event.ADDED_TO_STAGE, init); funzione privata init (e: Event = null) this.removeEventListener (Event.ADDED_TO_STAGE, init); stage.addEventListener (MouseEvent.MOUSE_MOVE, onMove);
Se spostiamo il palcoscenico
allineare a una funzione diversa, e chiamarla solo quando abbiamo uno stage, quindi siamo impostati. Se palcoscenico
esiste fin dall'inizio, andare avanti e correre dentro()
subito. In caso contrario, useremo dentro()
come funzione di listener di eventi per ADDED_TO_STAGE
, a quel punto avremo un valore di stage e possiamo eseguire il codice. Ora possiamo usare la classe per la connessione a IDE Sprite o completamente a livello di programmazione.
Funziona bene anche nelle classi di documenti. Quando si esegue un SWF da solo, la classe del documento ha accesso immediato a palcoscenico
. Se si carica quel file SWF in un altro SWF, il codice nello stack di inizializzazione della classe del documento viene eseguito prima che il file SWF caricato venga aggiunto al display. Un simile palcoscenico
-il trucco di controllo ti consentirà di lavorare con SWF sia come pezzo autonomo che come SWF caricato in un SWF contenente.
Grazie per aver letto questo suggerimento! Spero che tu sia illuminato un po 'su come si verifica l'errore 1009 e su come puoi eseguirne il debug. Restate sintonizzati per ulteriori suggerimenti rapidi su altri errori comuni.