Recebendo erro ao usar o método removeChild
-
22-07-2019 - |
Pergunta
Happy pré-Halloween todos:)
Meu problema hoje é um erro de DisplayObject que estou recebendo quando remover um objeto filho. Eu tenho o código que irá lançar (addChild) um recipiente de vídeo e controles de vídeo, bem como adicionar um botão fechar. Agora, o botão de fechar funciona bem e tudo , remover o vídeo e controles e eu sou poder escolher outro vídeo novamente, mas quando você clica perto a 2ª vez que recebo este erro:
ArgumentError: Erro # 2025: O DisplayObject fornecido deve ser filho do chamador. em flash.display :: DisplayObjectContainer / removeChild ()
Então, eu reduzi o problema para onde eu remover o videoContainer (que detém o objeto de vídeo)
Meu código para reproduzir os vídeos:
public function videoSwitch(videoName):void
{
nv.closeOut();
nv.resetNav = false;
if (!videoPlaying)
{
vc = new VideoClass(videoName, videoHolder);
vc.addEventListener("KillMovie", removePlayer);
container.addChild(videoContainer);
container.addChild(vc);
//container.addChildAt(videoContainer, 1);
//container.addChildAt(vc, 2);
videoPlaying = true;
closeVideo();
}
else if (videoPlaying)
{
vc.clearSource();
container.removeChild(videoContainer);
container.removeChild(vc);
vc = new VideoClass(videoName, videoHolder);
vc.addEventListener("KillMovie", removePlayer);
container.addChild(videoContainer);
container.addChild(vc);
//container.addChildAt(videoContainer, 1);
//container.addChildAt(vc, 2);
closeVideo();
}
trace("videoPlaying = "+videoPlaying+"\r");
}
A fechar código do player de vídeo: Você pode ver em meus comentários outro código Eu tentei, mas ainda obter o erro.
function closeVideo():void
{
closeBtn.visible = true;
closeBtn.x = 770;
closeBtn.y = 20;
closeBtn.buttonMode = true;
container.addChild(closeBtn);
closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
function closeButtonClicked(event:MouseEvent):void
{
vc.clearSource();
container.removeChild(videoContainer);
//container.removeChildAt(videoContainer, 1);
container.removeChild(vc);
videoPlaying = false;
closeBtn.visible = false;
}
}
Agora meu filme funciona bem, mas eu estou preocupado que isso aconteça erro no fundo (e aparecendo na minha janela de saída) acabará por causar um problema mais onde: (
Agradecemos antecipadamente para quaisquer olhos em um presente! :)
UPDATE: ! FIXO O problema era que eu retire a matança VC ouvinte, mas se esqueceu de remover o estúpido do botão Fechar mouse_event ouvinte: (
function addCloseButton():void
{
container.addChild(closeBtn);
closeBtn.addEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
function closeButtonClicked(event:MouseEvent):void
{
videoPlaying=false;
vc.clearSource();
removeContainerChildren(); // <- thx Joel!
closeBtn.removeEventListener(MouseEvent.MOUSE_UP, closeButtonClicked);
//^ Forgot this line - thx Jotham!
container.removeChild(closeBtn);
}
}
Não sei se este gráfico ajuda, mas:
Solução
Você já se remover o ouvinte? Você poderia muito bem ser tê-lo disparar várias vezes.
Outras dicas
aqui é uma abordagem para evitar o erro:
public function videoSwitch(videoName):void
{
nv.closeOut();
nv.resetNav = false;
if (videoPlaying)
{
vc.clearSource();
removeContainerChildren()
}
addContainerChildren();
closeVideo();
}
protected function removeContainerChildren():void
{
if(container.contains(videoContainer))
container.removeChild(videoContainer);
if(container.contains(vc))
{
container.removeChild(vc)
vc.removeEventListener("KillMovie", removePlayer)
}
}
protected function addContainerChildren():void
{
videoPlaying = true;
vc = new VideoClass(videoName, videoHolder);
vc.addEventListener("KillMovie", removePlayer, false, 0, true);
container.addChild(videoContainer);
container.addChild(vc);
trace("videoPlaying = "+videoPlaying+"\r");
}
Tente isto:
container.removeChild(container.videoContainer);
container.removeChild(container.vc);
Eu tenho um sentimento de que é algum outro pedaço de código causando o problema real. Este erro faria sentido se a variável videuPlaying tem mudado em outro lugar para que você estavam removendo algo que não existia ainda. Talvez verifique se você não está mudando esta variável em outro lugar.
Este é outro uber maneira hacky de fazer isso, não é normalmente recomendado, mas ele definitivamente irá assegurar que a videoContainer / vc é removido a partir de qualquer DisplayList
ele estiver ligado.
private function removeFromStack(target:DisplayObject):void
{
if (target.parent)
target.parent.removeChild(target);
}
private function removeVideo():void
{
removeFromStack(vc);
removeFromStack(videoContainer);
vc = videoContainer = null;
}
Apenas para re-itterate, esta não é a maneira preferida, mas vai funcionar sem erros. Se você começar a receber um erro "referência nula objeto não pode acessar", então como as pessoas anteriores têm sugerido, ouvintes de eventos ou algumas outras dependências ainda são realizadas pelos DisplayObject'
s em questão.
Espero que isso ajude