[转][Flash/Flex] 纠结的switch与AS3的XML处理,貌似发现AS3的一个BUG

本文发现了一个关于ActionScript 3 (AS3) 中XML处理的一个奇怪Bug,在特定条件下会导致TypeError错误。通过逐步调整代码结构,作者揭示了触发该Bug的具体条件,并提供了两种可行的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[url]http://bbs.9ria.com/thread-72294-1-1.html[/url]

资讯类型: 原创
来源页面:
资讯原标题:
资讯原作者: eko
我的评论:
对这篇文你有啥看法,跟贴说说吧!欢迎口水和板砖,哈哈。欢迎大家和我们一同分享更多资讯。
本帖最后由 eko 于 2011-1-13 17:21 编辑


嗯首先这是一则新闻,我发现了AS3下的一个bug,接下来我就和大家一起分享一下这个bug

请大家先在cs5中运行一下下面的类
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.IOErrorEvent;
import flash.events.Event;

var _name:String="eko";
var eko:XML=<setting><version>1.0.0</version><family name="fancy" age="27"/><family name="eko" age="30" /></setting>;
var _url:URLLoader=new URLLoader();
_url.addEventListener(IOErrorEvent.IO_ERROR,onLoadCom);
_url.load(new URLRequest("eko.xml"));
function onLoadCom(e:IOErrorEvent):void
{
switch(_name)
{
case "eko":
var _str4:String=eko.family.(@name=="eko").@age;
break;
}

}


报错
TypeError: Error #1010: 术语尚未定义,并且无任何属性。


大家可能认为我的XML语句写错了
那么我们把var _str4:String=eko.family.(@name=="eko").@age;;注掉,打印eko.family.(@name=="eko").@age;看看
修改后的局部代码为:
trace(eko.family.(@name=="eko").@age);
//var _str4:String=eko.family.(@name=="eko").@age;


输出:
30

结果证明我的XML处理是正确的。那为什么会出现这种事情呢。不急,我们再来修改一下类
我们给case后面加上{}
case "eko":
{
trace(eko.family.(@name=="eko").@age);
var _str4:String=eko.family.(@name=="eko").@age;
break;
}


输出正常,也没有报错。
是不是很神奇?不着急,我们接下来再在最初的代码中这么处理,我们把
var _str4:String=eko.family.(@name=="eko").@age;


换个写法,写成

var _str4:String;
_str4=eko.family.(@name=="eko").@age;


顺便打印一下_str4,输出正常,并且不报错。

至此,大家一定认为最初的switch有问题,但事实并不是如此,我们再来做个试验,把其中的异步去掉,将代码修改如下
var _name:String="eko";
var eko:XML=<setting><version>1.0.0</version><family name="fancy" age="27"/><family name="eko" age="30" /></setting>;
switch(_name)
{
case "eko":
var _str4:String=eko.family.(@name=="eko").@age;
trace(_str4);
break;
}



它,它,它又是正常的……

如果大家认为这段代码没有问题,那么请大家把上面的代码改写成文档类,我们再试验一下

package
{
import flash.display.Sprite;

public class Main extends Sprite
{
private var _name:String="eko";
private var eko:XML=<setting><version>1.0.0</version><family name="fancy" age="27"/><family name="eko" age="30" /></setting>;
public function Main()
{
switch(_name)
{
case "eko":
var _str4:String=eko.family.(@name=="eko").@age;
trace(_str4);
break;
}
}

}

}


再CS5中设置文档类,它又报错了

TypeError: Error #1010: 术语尚未定义,并且无任何属性。


我的文档类写错了?
重复之前的操作给case :后面加上{},或者把先申明_str4然后再赋值


var _str4:String;
_str4=eko.family.(@name=="eko").@age;


它又正常了。
这是怎么回事呢?
我不知道,不过我总结如下

在CS5中帧上写代码,具备以下条件就会出错。

1 异步(去load一个外部文件,无论成功与否)
2 处于switch的第一个case分支中(看下一楼“沙发”的补充)
3 在申明变量的同时进行XML查询匹配并赋值(var _str4:String=eko.version或者给version加个name属性,进行var _str4:String=eko.version.@name是正确的)

如果是在类中,则无论异步与否只要具备以上2,3两点就会报错。

解决办法有两个:
第一种方法: 变量申明和赋值分开写
第二种方法: 给case后面加{}



package
{
import flash.display.Sprite;

public class Main extends Sprite
{
private var eko:XML=<setting><version name="sandal">1.0.0</version><family name="fancy" age="27"/><family name="eko" age="30" /></setting>;
public function Main()
{

onTest("fancy");
onTest("eko");

}
private function onTest(_name:String):void
{
switch(_name)
{
case "eko":
var _str4:String=eko.family.(@name=="eko").@age;
trace(_str4);
break;
case "fancy":
var _str3:String=eko.family.(@name=="eko").@age;
trace(_str3);
break;
}
}

}

}


大家可以看到,两个case分支执行同样的代码,第一个分支case "eko"报错了,case "fancy"却是正常的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值