委托的底层是什么?
在 C# 中,委托(delegate
)是一种类型安全的函数指针。它本质上是一个对象,封装了对方法的引用。每个委托包含以下信息:
- 方法指针:指向实际方法的内存地址。
- 目标对象:对于实例方法,委托还保存了一个指向目标对象的引用。
- 方法参数:定义了委托可以接受的参数类型。
委托与Unity对象生命周期的关系?
Unity中,假设委托的目标对象被销毁,那么执行委托时会发生什么?看下面一个例子:
public class Sphere : MonoBehaviour
{
public Action myAction;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
myAction.Invoke();
}
}
}
public class Cube : MonoBehaviour
{
private void Start()
{
GameObject.Find("Sphere").GetComponent<Sphere>().myAction = TestPrint;
Destroy(gameObject);
}
public void TestPrint()
{
Debug.Log("Cube's method");
}
}
我的场景中有一个球对象,身上挂载了Sphere,有一个立方体对象,身上挂载了Cube,在游戏开始时,Cube会把自己的TestPrint方法注册到Sphere的委托中,销毁自己的gameObject,之后当我点击鼠标时,是否还能正确的执行Sphere的委托?
答案是可以正常打印Cube's method。
在 Unity 中,Destroy(gameObject)
方法会销毁游戏对象,但是挂载在其上的 脚本实例 并不会立即被垃圾回收,因为还有对该脚本实例的引用存在。在以上案例中,myAction
委托持有了对 Cube
脚本实例的引用,因此该实例不会被立即回收,因此可以正常执行TestPrint方法。
值得注意的是,假设TestPrint方法内部访问了Cube的任何 Unity 组件,例如gameObject、transform
等。由于游戏对象已被销毁,会引发 NullReferenceException。