Получение ошибки при использовании метода removeChild
-
22-07-2019 - |
Вопрос
Всем счастливого предХэллоуина :)
Моя проблема сегодня — ошибка DisplayObject, которую я получаю при удалении дочернего объекта.У меня есть код, который запускает (addChild) видеоконтейнер и элементы управления видео, а также добавляет кнопку закрытия. Теперь кнопка закрытия работает нормально и все, удалив видео и элементы управления, и я снова могу выбрать другое видео, но когда вы нажимаете «Закрыть» второй раз, я получаю эту ошибку:
АргументОшибка:Ошибка № 2025:Предоставленный DisplayObject должен быть дочерним по отношению к вызывающему объекту.в flash.display::DisplayObjectContainer/removeChild()
Итак, я сузил проблему до того, где я удаляю видеоконтейнер (который содержит видеообъект)
Мой код для воспроизведения видео:
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");
}
Завершающий код видеоплеера:В моих комментариях вы можете увидеть другой код, который я пробовал, но все равно получаю ошибку.
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;
}
}
Сейчас мой фильм работает нормально, но я беспокоюсь, что эта ошибка, происходящая в фоновом режиме (и появляющаяся в моем окне вывода), в конечном итоге вызовет проблему в другом месте :(
Заранее спасибо за внимание к этому!:)
ОБНОВЛЯТЬ: ЗАФИКСИРОВАННЫЙ! Проблема заключалась в том, что я удалил прослушиватель kill VC, но забыл удалить дурацкий прослушиватель Close Button Mouse_Event :(
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);
}
}
Не знаю, поможет ли этот рисунок, но:
Решение
Вы когда-нибудь удаляли прослушиватель?Вполне возможно, что он сработает несколько раз.
Другие советы
вот один из способов избежать ошибки:
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");
}
Попробуй это:
container.removeChild(container.videoContainer);
container.removeChild(container.vc);
У меня такое ощущение, что реальную проблему вызывает какой-то другой фрагмент кода.Эта ошибка имела бы смысл, если бы переменная videoPlaying была изменена где-то еще и вы удалили что-то, чего еще не существовало.Возможно, проверьте, не меняете ли вы эту переменную где-то еще.
Это еще один очень хакерский способ сделать это, обычно не рекомендуемый, но он определенно гарантирует, что videoContainer/vc будет удален из любого места. DisplayList
оно включено.
private function removeFromStack(target:DisplayObject):void
{
if (target.parent)
target.parent.removeChild(target);
}
private function removeVideo():void
{
removeFromStack(vc);
removeFromStack(videoContainer);
vc = videoContainer = null;
}
Еще раз повторю: это не предпочтительный способ, но он будет работать без ошибок.Если вы начинаете получать ошибку «невозможно получить доступ к нулевой ссылке на объект», то, как предположили предыдущие люди, прослушиватели событий или некоторые другие зависимости по-прежнему удерживаются DisplayObject'
это под вопросом.
Надеюсь это поможет