ActionScript 3
Informazioni su "Errore 1009: impossibile accedere a una proprietà oa un metodo di riferimento a un oggetto nullo"
Ricerca…
introduzione
null
. Gli esempi forniti illustrano vari casi in cui si verifica questo errore, insieme ad alcune raccomandazioni su come mitigare l'errore.
Osservazioni
Il temuto e spesso chiesto "Errore 1009: impossibile accedere a una proprietà o metodo di un riferimento a oggetto nullo" è un segnale che alcuni dati appaiono nulli, ma viene tentato di essere usato come oggetto popolato. Esistono molti tipi di problemi che possono causare questo comportamento e ognuno deve essere verificato rispetto al codice in cui si è verificato l'errore.
Stage non disponibile
A volte gli sviluppatori scrivono un codice che desidera accedere allo stage
o allo stage
Flash per aggiungere ascoltatori. Può funzionare per la prima volta, quindi all'improvviso non funziona e genera l'errore 1009. Il codice in questione può essere anche sulla timeline, poiché è la prima iniziativa ad aggiungere codice e molti tutorial ancora esistenti strato di codice temporale per posizionare il codice.
public class Main extends MovieClip {
public function Main() {
stage.addEventListener(Event.ENTER_FRAME,update); // here
Il motivo per cui questo codice non funziona è semplice: un oggetto di visualizzazione viene prima istanziato, quindi aggiunto all'elenco di visualizzazione e mentre è fuori dall'elenco di visualizzazione, lo stage
è nullo.
Peggio ancora se il codice come questo:
stage.addEventListener(Event.ENTER_FRAME,update); // here
è posto sulla timeline. Può anche funzionare per un po 'di tempo, mentre l'oggetto Main
viene schiaffeggiato sullo stage tramite la GUI. Quindi, il loro SWF viene caricato da un altro SWF e, all'improvviso, il codice si interrompe. Ciò accade perché i frame del Main
sono costruiti in modo diverso quando il file SWF viene caricato direttamente dal player e quando il caricamento viene elaborato in modo asincrono. La soluzione è usare il listener Event.ADDED_TO_STAGE
e mettere tutto il codice che indirizzi stage in esso, e mettere il listener stesso in un file AS invece della timeline.
Typecast non valido
function listener(e:Event):void {
var m:MovieClip=e.target as MovieClip;
m.x++;
}
Se tale listener è collegato a un oggetto che non è un discendente MovieClip
(ad esempio, uno Sprite
), il typecast fallirà e qualsiasi successiva operazione con il suo risultato genererà l'errore 1009.
Oggetto non istintivo
var a:Object;
trace(a); // null
trace(a.b); // Error 1009
Qui viene dichiarato un riferimento a un oggetto, ma non viene mai assegnato un valore, sia esso con new
o l'assegnazione di un valore non nullo. Richiedere le sue proprietà o il metodo genera un errore 1009.
Espressione a più livelli
x=anObject.aProperty.anotherProperty.getSomething().data;
Qui, qualsiasi oggetto prima del punto può risultare null, e l'utilizzo di metodi che restituiscono oggetti complessi aumenta solo la complicazione di eseguire il debug dell'errore nullo. Caso peggiore se il metodo è soggetto a guasti estranei, ad esempio il recupero dei dati attraverso la rete.
Risultato della funzione non elaborata
s=this.getChildByName("garbage");
if (s.parent==this) {...}
getChildByName()
è una delle molte funzioni che può restituire null se si è verificato un errore durante l'elaborazione del suo input. Pertanto, se si riceve un oggetto da qualsiasi funzione che può eventualmente restituire null, verificare prima null. Qui, una proprietà viene interrogata istantaneamente senza prima verificare se s
è nullo, questo genererà l'errore 1009.
Ascoltatore di eventi dimenticato
addEventListener(Event.ENTER_FRAME,moveChild);
function moveChild(e:Event):void {
childMC.x++;
if (childMC.x>1000) {
gotoAndStop(2);
}
}
Questo esempio sposterà il childMC
(aggiunto a Main
in fase di progettazione) ma getterà istantaneamente un 1009 non appena gotoAndStop()
viene invocato, se quel childMC
non esiste sul frame 2. Il motivo principale per questo è che ogni volta che un playhead passa un fotogramma chiave (un fotogramma che non eredita il set di oggetti del fotogramma precedente), utilizzando gotoAndStop()
, gotoAndPlay()
con il fotogramma di destinazione separato dal fotogramma corrente da un fotogramma chiave o dalla riproduzione normale se il file SWF è un animazione, i contenuti del frame corrente vengono distrutti e i nuovi contenuti vengono creati utilizzando i dati memorizzati dalla GUI. Quindi, se il nuovo frame non ha un figlio chiamato childMC
, la richiesta di proprietà restituirà null e verrà lanciato 1009.
Lo stesso principio si applica se aggiungi due listener di eventi, ma ne rimuovi solo uno o aggiungi un listener a un oggetto, ma prova a rimuoverlo da un altro. La chiamata removeEventListener
non ti avviserà se l'oggetto non ha un rispettivo listener di eventi collegato, quindi leggi il codice che aggiunge e rimuove attentamente i listener di eventi.
Nota anche: Usando gli oggetti Timer
, la chiamata a setInterval()
e setTimeout()
crea anche listener di eventi, e anche questi dovrebbero essere cancellati correttamente.
Riferimento invalidato a un oggetto basato su frame
A volte gotoAndStop()
viene chiamato nel mezzo del codice che fa riferimento ad alcune proprietà basate su frame. Ma, subito dopo la modifica del frame, tutti i collegamenti alle proprietà esistenti sul frame corrente vengono invalidati, quindi qualsiasi elaborazione che li coinvolge deve essere immediatamente interrotta.
Esistono due scenari generali di tale elaborazione: Primo, un ciclo non termina dopo la chiamata a gotoAndStop()
, come qui:
for each (bullet in bullets) {
if (player.hitTestObject(bullet)) gotoAndStop("gameOver");
}
Qui, un errore 1009 significa che il player
MC è stato distrutto durante l'elaborazione della chiamata gotoAndStop()
, ma il ciclo continua, e fa riferimento al link now-null per ottenere hitTestObject()
da. Se la condizione dovesse dire if (bullet.hitTestObject(player))
invece, l'errore sarebbe # 2007 "Il parametro hitTestObject non deve essere nullo". La soluzione è inserire un'istruzione return
dopo aver chiamato gotoAndStop()
.
Il secondo caso riguarda più listener di eventi sullo stesso evento. Come questo:
stage.addEventListener(Event.ENTER_FRAME,func1);
stage.addEventListener(Event.ENTER_FRAME,func2);
function func1(e:Event):void {
if (condition()) {
gotoAndStop(2);
}
}
Qui, se condition()
è true, il primo listener eseguirà gotoAndStop()
, ma il secondo listener verrebbe comunque eseguito e, se questo fa riferimento a oggetti sul frame, verrà generato un errore 1009. La soluzione è evitare più ascoltatori su un singolo evento, in un singolo oggetto, è meglio avere un ascoltatore che gestisca tutte le situazioni su quell'evento e che possa terminare correttamente se è necessario un cambio di frame.