You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AS3中Loader加载位图后移除时报错:Parameter child must be non-null

问题分析与解决方案

从你的代码来看,核心问题出在异步回调函数的this指向错误,以及异步加载场景下index变量的作用域问题——这导致你根本没把图片正确存储到目标容器的属性里,移除时自然找不到对象。

具体问题拆解

  • this指向混乱:
    在ldr_complete事件回调里,默认的this并不是你外部addStuff函数里的容器对象(比如类实例或舞台),而是触发事件的LoaderInfo实例。所以你在回调里执行this["photo" + index] = new Bitmap(...)时,实际上是把Bitmap对象存在了LoaderInfo上,而非你预期的容器对象。这就导致removeStuff里访问this["photo" + i]时得到null,调用removeChild(null)就会抛出Parameter child must be non-null错误。

  • index变量的异步作用域问题:
    如果addStuff被多次调用,index作为共享变量,当图片加载完成触发回调时,index可能已经被更新为最新值,这会导致你把图片存到错误的属性名里,后续移除也找不到正确的对象。

修复后的代码示例

修正addStuff函数

function addStuff(){
    // 保存外部的this引用,避免回调里this指向错误
    var self = this;
    // 保存当前的index值,避免异步回调时index已变化
    var currentIndex = index;

    this["otherstuff" + currentIndex] = new TextField;
    addChild(this["otherstuff" + currentIndex]);

    var IMAGE_URL:String = arraywithstuff[currentIndex][2];
    var ldr:Loader = new Loader();
    // 把当前index绑定到Loader对象上,方便回调里获取
    ldr.currentIndex = currentIndex;
    ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, ldr_complete);
    ldr.load(new URLRequest(IMAGE_URL));

    function ldr_complete(evt:Event):void {
        var loader:Loader = evt.target.loader;
        var bmp:Bitmap = loader.content as Bitmap;
        // 使用之前保存的self来访问目标容器
        self["photo" + loader.currentIndex] = new Bitmap(bmp.bitmapData);
        self.addChild(self["photo" + loader.currentIndex]);
        // 移除事件监听,避免内存泄漏
        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, ldr_complete);
    }
}

优化removeStuff函数(增加存在性检查)

function removeStuff(){
    for (var i = 0; i < maxindex; i++){
        // 先检查对象是否存在且是当前容器的子元素,再移除
        var otherStuff = this["otherstuff" + i];
        if (otherStuff && contains(otherStuff)){
            removeChild(otherStuff);
            // 清空属性,避免内存泄漏
            delete this["otherstuff" + i];
        }

        var photo = this["photo" + i];
        if (photo && contains(photo)){
            removeChild(photo);
            delete this["photo" + i];
        }
    }
}

额外注意事项

  • 异步回调完成后一定要移除事件监听,避免内存泄漏(修复代码已添加此逻辑)。
  • 如果index是全局变量,建议改成局部变量或用闭包封装,避免多次调用addStuff时的变量污染。
  • 可以考虑用数组存储所有添加的元素(比如var photoList:Array = []),代替动态属性名,管理起来会更直观方便。

内容的提问来源于stack exchange,提问作者Magnus Myrgård

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:34:43