2

祝大家万圣节前快乐 :)

我今天的问题是删除子对象时出现的 DisplayObject 错误。我有将启动(addChild)视频容器和视频控件以及添加关闭按钮的代码。现在关闭按钮工作正常,一切正常,删除视频和控件,我可以再次选择另一个视频,但是当您第二次单击关闭时,我收到此错误:

ArgumentError:错误 #2025:提供的 DisplayObject 必须是调用者的子对象。在 flash.display::DisplayObjectContainer/removeChild()

因此,我将问题缩小到删除 videoContainer (包含视频对象)的位置

我播放视频的代码:

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);
    }
}

不知道这张图是否有帮助,但是: 替代文字

4

5 回答 5

2

这是避免错误的一种方法:

    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");
    }
于 2009-10-30T20:38:38.237 回答
1

试试这个:

 container.removeChild(container.videoContainer);
 container.removeChild(container.vc);
于 2009-10-30T20:15:12.637 回答
1

我有一种感觉,是其他一些代码导致了实际问题。如果在其他地方更改了 videoPlaying 变量以使您删除尚不存在的内容,则此错误将有意义。也许检查您没有在其他地方更改此变量。

于 2009-10-31T01:28:44.250 回答
1

您是否曾经删除过侦听器?您很可能会多次触发它。

于 2009-10-31T08:20:49.883 回答
1

这是另一种超级 hacky 的方式,通常不推荐,但它肯定会确保 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'问题的 s 持有。

希望这可以帮助

于 2009-10-31T15:45:14.380 回答