转自:
http://blog.csdn.net/lapal/archive/2010/12/12/6070903.aspx
个人感觉as3 的值和引用略微有点乱,需要整理一下。
跟这两者比较有关系的是“赋值”和“函数传参”两个行为,期间又需要分“基元类型”和“对象”来讨论。
我们知道flash as语言中所有的数据类型都继承自Object,包括基元数据类型,但是在值和引用操作时它们的确需要区别对待。
我们将基元数据类型称为“非结构对象”,与之对应的其他Object称为“结构对象”。
下面将进行几种实验,结论大概就是
1、 基元数据类型按照值操作,代表基元数据的非结构对象也是按照值操作的。
2、 结构对象一般按照“引用”操作,但需要注意交换赋值的情况
3、 As3中的“引用”操作其实不是真正意义上的引用,只是类似于“指针”传递的一种伪“引用”。As3中所有操作底层意义都是值操作,只不过针对结构对象时是“指针”值的值操作。
4、 As3中的函数传参,对基元类型相当于新副本的值操作。对结构对象,相当于“指针”值新副本的值操作。
5、 必要的时候使用深层次拷贝操作,特别是在多层次框架结构中。
=================
基元类型(包括 Boolean、Number、int、uint 和 String)
赋值:按照值操作。
var a:int=3;
var b:int=a;
b=6;
trace(a,b);// 3 6 即 b的改变不会带来a的改变
函数传参:按照值操作
var a:int=3;
function f1(b:int):void{
b=6;
}
f1(a);
trace(a);//3 即在函数内部生成了新副本,其变化不会带来a的改变
与前面的赋值操作是等价一致的
=================
对象Object
赋值:按照引用操作
var a:Object={x:1,y:2};
var b:Object=a;
b.x=6;
trace(a.x);//6 即 b的改变会带来a的改变
----下面模拟复杂对象赋值---
var c:Object={i:10,j:11}
var a:Object={x:1,y:c};
var d:Object=a.y;
var b:Object=a;
d.i=6;
trace(a.y.i);//6
trace(b.y.i);//6 这里需要格外注意,as3的引用行为是无孔不入的,自定义对象的子对象遭遇引用操作,特别是多层架构中,隐蔽的引用操作会带来意想不到的问题。
函数传参:结构对象按引用操作;代表基元类型的非结构对象,按值操作
var a:Object={x:3};
function f1(b:Object):void{
b.x=6;
}
f1(a);
trace(a.x);//6 一如既往的引用操作,但请注意下面
-----代表基元类型的对象----
var a:Object=Object(3);
function f1(b:Object):void{
b=6;
}
f1(a);
trace(a);//3 如果Object代表基元类型,那则按值来操作
=============================
貌似到这里关于as3的值和引用归类总结已经结束了,其实不是的。
看下面一段代码。
var a:Object={x:1};
var b:Object={x:4};
var c:Object;
c=a;
a=b;
b=c;
trace(a.x,b.x);
结果不出意外的是 4 1 ,我们继续看下面代码
var a:Object={x:1};
var b:Object={x:4};
function swapObj(i:Object,j:Object):void
{
var k:Object;
k=i;
i=j;
j=k;
}
swapObj (a,b);
trace(a.x,b.x);
结果是什么呢?却不是我们想的 4 1,而是 1 4
这里发生了什么故事,我们继续试验
var a:Object={x:1};
var b:Object={x:4};
function swapArr(i:Object,j:Object):void
{
var k:Object;
k=i;
k.x+=10;
trace(k.x,a.x,b.x,i.x,j.x);
i=j;
trace(k.x,a.x,b.x,i.x,j.x);
j=k;
trace(k.x,a.x,b.x,i.x,j.x);
}
swapArr(a,b);
trace(a.x,b.x);
------------------------
11 11 4 11 4
11 11 4 4 4
11 11 4 4 11
11 4
看起来很让人头疼,我直接画图摆结论吧,as3所谓的引用操作过程中只是指针值的操作,并不是真的引用。
至此,as3值和引用操作真正有价值的东西才算讲了一点点。
要善用函数返回值,不要想当然的把对象传进去就认为函数自己会按照引用操作去完美的工作。
遇到可能出现这种问题的情况,要善用深层次拷贝。
比如比较常用的Array,默认并没有提供clone函数,那就按照如下操作进行深层次拷贝,来保证代码流转过程中的逻辑正确和减少未知引用关联。
import flash.utils.ByteArray;
function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
相关推荐
let receiverVC = segue.destination as! ReceiverViewController receiverVC.delegate = self } } ``` 对于"双向传值",这意味着不仅可以从发送者到接收者,还可以从接收者回传数据给发送者。这可以通过添加更...
标题提到的"IOS界面之间通过委托传值"是一种常用且灵活的方法,它基于Objective-C或Swift的委托设计模式(Delegate Pattern)。这种模式允许一个对象(在这里是发送者)通知另一个对象(接收者)关于某些事件或操作...
使用`NotificationCenter`可以广播数据给所有感兴趣的对象,适用于多对多的数据传递,但需谨慎使用以避免内存泄漏。 ```swift // 发送通知 let center = NotificationCenter.default center.post(name: ....
与值传递相反,引用传递传递的是对象的引用或地址。这意味着函数可以改变原始变量的值。例如,在Java中: ```java public class Main { public static void main(String[] args) { int[] arr = {1, 2, 3}; ...
3. **两窗体传值过程**: - **子窗体定义委托和事件**:首先,子窗体定义一个委托类型,例如`ValueChangeEvent`,它描述了处理事件的方法应该有的签名。接着,子窗体声明一个基于这个委托类型的事件,比如`...
3. **设置代理**:在源视图控制器(ViewControllerA)中,创建一个对目标视图控制器的引用,并将其设置为代理。通常,这会在用户触发某个操作(如点击按钮)时发生。 ```swift class ViewControllerA: ...
我们将主要讨论手动 segue,因为它是从后向前传值的常用方式。 1. **创建 segue**:在 storyboard 中,选中源视图控制器,然后按住 Control 键,拖动到目标视图控制器上,松开鼠标后选择 segue 类型,如 `Show`、`...
- 委托模式要求遵循协议的对象必须是类,因为Swift中的协议不能被结构体或枚举遵循,它们不支持引用计数。 - 使用委托模式进行反向传值时,确保在适当的时机设置和清除代理,避免出现意外的回调。 总结来说,通过...
3. **传值的实现**: 事件传值通常通过两种方式实现:参数传递和公共变量。在VB6.0中,可以通过在事件处理程序中设置对象的属性来传递值,或者创建全局变量让不同对象共享数据。 4. **按钮事件**: 在本示例中,...
发送值的对象会持有代理对象的引用,并在适当的时候调用协议中的方法来传递数据。例如,创建一个`ChildViewControllerDelegate`协议: ```objc @protocol ChildViewControllerDelegate - (void)...
3. 当委托对象不再存在时,确保检查委托是否为空,避免调用无效的代理方法。 4. 使用可选链(Optional Chaining)在Swift中调用委托方法,以防止在委托未设置时崩溃。 通过以上步骤,你可以利用委托有效地在iOS应用...
本篇文章将详细讲解如何使用jQuery与ASP.NET VB.NET后台进行传值处理。 首先,理解jQuery的Ajax方法是关键。$.ajax()是jQuery的核心方法,用于发起异步HTTP(Ajax)请求。在这个例子中,我们可以使用它来向服务器...
在这里,我们可以获取到即将要显示的接收者视图控制器(ViewController B)的引用,并通过这个引用传递数据。 ```swift override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue....
- **按引用传递(By Reference)**:虽然ActionScript不直接支持按引用传递,但可以通过传递对象或数组来间接实现。因为对象和数组的引用(而不是它们的内容)会被传递,所以函数可以修改这些对象或数组的内容。 4...
在多线程环境中,需要注意GCD(Grand Central Dispatch)的内存管理,防止Block中引用的对象被过早释放(即所谓的循环引用或强引用闭环)。使用__block关键字可以解决这个问题,但在Swift中通常通过弱引用来避免这种...
本文实例讲述了javascript引用赋值(地址传值)用法。分享给大家供大家参考。具体如下: javascript在默认情况下,数组、对象和函数是引用赋值,如下代码所示: 代码如下:<html> <head> [removed] var ...
- **函数参数**:介绍传值调用、引用调用等不同类型的参数传递方式。 - **递归调用**:探讨递归函数的工作原理及其内存栈的使用情况。 #### 六、一维数组与字符串 一维数组与字符串是编程中常用的线性数据结构。本...
1. **创建ShellWindows对象**:通过`Dim IEList As New ShellWindows`创建一个`ShellWindows`对象,用于管理所有的IE浏览器窗口。 2. **遍历IE窗口**:使用`For Each`循环遍历所有打开的IE窗口。 3. **匹配目标窗口*...
- 参数传递有传值和传引用两种方式,VB默认使用传值,但可以通过ByRef关键字实现传引用。 4. **作用域**: - 变量、过程的作用域决定了它们在程序中的可见性和生命周期。局部变量只在定义它的过程或函数内部可见...