as3 Loader.load()时出现错误“Error #2025: 提供的 DisplayObject 必须是调用者的子级”的解决方案
最近因为项目需要,所以开始了as3的开发之旅。今天遇到一个问题,就是在用flash.display.Loader的load()方法的时候,如果反复调用load(),就会出现“Error #2025: 提供的 DisplayObject 必须是调用者的子级”的错误,核心代码如下:
代码
public function loadPhoto(picURL):void {
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
content.addChild(_loader.content);
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
content.addChild(_loader.content);
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
搜索了相关的问题,说是每次用到Loader对象的时候,都去new一下,就可以避免这个错误,试了试,果然可以正常使用了,代码改成这样:
代码
public function loadPhoto(picURL):void {
_loader = new Loader(); //这里多加了一条new Loader()的语句
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
content.addChild(_loader.content);
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
_loader = new Loader(); //这里多加了一条new Loader()的语句
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
content.addChild(_loader.content);
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
不过每次都去new的话,内存开销肯定受不了,所以不敢采用这个方案,于是请教了涵涵同学,丫说可以把Loader对象直接作为Sprite对象的子节点,也就是改成这样
代码
public function loadPhoto(picURL):void {
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
if(content.numChildren==0){ //这里加上了只有第一次装载时才add到容器中的判断
content.addChild(_loader); //这里直接添加_loader对象,因为Loader也是从DisplayObject类继承过来的,所以能直接用
}
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
if(content.numChildren==0){ //这里加上了只有第一次装载时才add到容器中的判断
content.addChild(_loader); //这里直接添加_loader对象,因为Loader也是从DisplayObject类继承过来的,所以能直接用
}
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
果然这样直接就可以用,而且不需要每次都去new了。
为什么会出现这种情况呢?
我又把代码改回去调试了一下:
trace(_loader.content.parent);
content.addChild(_loader.content);
trace(_loader.content.parent);
输出:
[object Loader]
由此可见,_loader.content的父节点被改变了(废话,因为被addChild到另外的DisplayObject里了),所以可能Loader的load()方法在处理content的时候,用到了content.parent这个对象,结果因为parent被改变了,所以出错了,有研究过as3类库源码的同学可以出来帮忙说明一下下^_^。
所以之前的代码改为这样既可:
代码
public function loadPhoto(picURL):void {
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
if(content.numChildren==0){
content.addChild(_loader);
}
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}
_loader.load(new URLRequest(picURL));
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad);
_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
}
protected function onLoad(event:Event):void {
if(content.numChildren==0){
content.addChild(_loader);
}
_eventDispatcher.dispatchEvent(new Event(PhotoLoader.EVENTS_LOAD));
}