首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Actionscript 3-引用与值

Actionscript 3-引用与值
EN

Stack Overflow用户
提问于 2010-02-17 22:15:17
回答 4查看 4.5K关注 0票数 4

我以为我已经在AS3中找到了引用,但是下面的行为让我感到困惑:

代码语言:javascript
运行
复制
// declarations for named individual reference later on
var myAmbientSound:Sound;
var myAmbientSoundLocation:String = "http://ambient_sound_location";

var myPeriodicSound:Sound;
var myPeriodicSoundLocation:String = "http://periodic_sound_location";

var myOccasionalSound:Sound;
var myOccasionalSoundLocation:String = "http://occasional_sound_location";

// for iterating through initialization routines
var mySoundArray:Array = [myAmbientSound, myPeriodicSound, myOccasionalSound];
var mySoundLocation:Array = [myAmbientSoundLocation, myPeriodicSoundLocation, myOccasionalSoundLocation];

// iterate through the array and initialize
for(var i:int = 0; i < mySoundArray.length; i++) {
    mySoundArray[i] = new Sound();
    mySoundArray[i].load(new URLRequest(mySoundLocation[i]));
}

此时,我认为mySoundArray[0]将引用与myAmbientSound相同的对象;然而,访问myAmbientSound会抛出空指针异常,而mySoundArray[0]则按预期工作并引用Sound对象。我在这里误解了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-02-17 22:44:51

它更像是java引用变量,而不是C指针。

代码语言:javascript
运行
复制
var myAmbientSound:Sound;
var myPeriodicSound:Sound;
var myOccasionalSound:Sound;
//these variables are not initialized and hence contain null values

现在创建一个包含这些变量的当前值(null)的数组

代码语言:javascript
运行
复制
var mySoundArray:Array = [myAmbientSound, myPeriodicSound, myOccasionalSound];

该数组现在包含三个空值[null, null, null],而不是您期望它包含的三个指向Sound对象的指针。

现在,当您调用mySoundArray[0] = new Sound();时,将创建一个新的Sound对象,并将其地址分配给数组的第一个位置-它不会修改myAmbientSound变量。

票数 7
EN

Stack Overflow用户

发布于 2010-02-18 04:58:43

由于其他人已经花时间提出了一些非常好的解释,所以我将尝试解决您隐含的问题:

在这一点上,我认为mySoundArray[0]会引用与myAmbientSound相同的对象

但是myAmbiendSound没有引用任何东西。从你的代码中:

代码语言:javascript
运行
复制
var myAmbientSound:Sound;

上面只是创建了一个Sound类型的局部变量,一个潜在的引用。用外行术语来说,一个可以指向某物的“手指”。所有局部变量都是引用。顺便说一下,并非所有引用都是局部变量,对象属性也是引用,就像ArrayVector元素一样。无论如何,上面的表达式并没有创建Sound类的对象。它只声明了一个局部变量,可以引用Sound类的对象。在声明时,它有一个特殊的值undefined

声明一个类似上面的变量和给它赋值是有区别的。Operator new创建一个对象并返回对该对象的引用。赋值运算符=的结果是引用左边的任何东西,大体上就是引用右边的东西。

让局部变量引用对象的一种方法是:

代码语言:javascript
运行
复制
myAmbientSound = new Sound();

然而,在您的示例中,正如我所说的,myAmbientSound变量有一个特殊的undefined值,因为您只是声明了它,并且还没有给它赋值。此外,正如我们从代码中看到的,在代码片段的整个运行时,它不会引用任何内容。

现在,在我用下面这行代码解释您最终要放入数组中的内容之前:

代码语言:javascript
运行
复制
 var mySoundArray:Array = [ myAmbientSound, ...

,你必须记住数组元素,就像对象属性一样,也是引用--例如,像mySoundArray[1]一样,mySoundArray[0]可以引用一个对象,等等。

上面的代码行声明了一个新的局部变量使其引用了一个新的数组对象。在一条语句中声明和定义。

现在,因为我们已经确定您的局部变量myAmbiendSound包含特殊的undefined值,所以您的第一个数组元素最终引用了相同的值- undefined最初为。在稍后的循环中,您让第一个元素(或者,如果我们要谨慎一些,就是变量i引用的数量的元素)引用一个新的Sound对象。在这一点上(就像我们观察到的那样,对于整个代码段而言),由于myAmbiendSoundundefined,所以将两者进行相等比较将失败-它们不引用相同的对象,它们引用的对象也被视为“相等”( =如何在AS3中工作是另一个主题)-前者是undefined,而后者指向Sound对象。

此外,还有一个小更正:“访问”对象不会导致运行时异常。试图访问没有指向对象的引用的属性(使用点符号语法),但是会导致运行时异常。这就好像你写了trace(null.foo) - null不是一个对象,当然也没有名为foo的属性。undefined也是如此。

顺便说一下,null == undefinedtrue,而null === undefinedfalse。只是说说而已。在很少的情况下(当然,取决于),您将不得不遵守这一细节。

我希望这能把事情弄清楚。我认为这是对前面所说的所有内容的补充。

票数 3
EN

Stack Overflow用户

发布于 2010-02-17 23:07:26

通常,ActionScript、Java和其他语言中的引用与C/C++中的引用不同。如果引用像在C/C++中一样工作,那么您编写的代码将是正确的,并且可以按照您的预期工作。通常,您应该尝试将引用视为自动取消引用的指针。您的代码是C/C++引用和现代引用之间区别的一个很好的例子。

以下是此行为应用于垃圾收集器时的后果示例:

代码语言:javascript
运行
复制
var someRef:Sound = new Sound();
someRef = null;

那么我在第一行中创建的Sound对象仍然存在,并且可能会继续存在。记住这一点很重要,因为如果您在AS3中注册事件侦听器,则会创建一个对它们的额外引用,以防止它们被GC销毁。这就是为什么您几乎总是应该使用对AddEventListener的完整调用,强制它使用弱引用(GC不计入弱引用)。

此外,请记住,在AS3中,所有函数调用都是ByVal。所以这段代码不能工作:

代码语言:javascript
运行
复制
function initSound(a:Sound, b:String):void {
    a = new Sound();
    a.load(new URLRequest(b);
}

var myAmbientSound:Sound;
var myAmbientSoundLocation:String = "http://ambient_sound_location";
initSound(myAmbientSound, myAmbientSoundLocation);

好消息是,大多数具有内置垃圾收集的语言都有相同的引用行为,所以一旦掌握了它的诀窍,您就能够更快地掌握这些语言。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2281320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档