c# - 删除委托的目标后如何安全地使用操作委托
问题描述
我通常使用委托进行回调。例如,我在统一脚本中的管理器中声明 Action 委托,并在调用 OnEnable 时注册委托,并在我的 Monobehaviuor 派生脚本中调用 OnDisable 时取消订阅。但我知道,如果我在错误的时间反抗和反抗,也许会很危险。例如,如果对象被某人删除。委托目标将为空。然后不需要的委托回调就可以了。因此,我想在委托执行时检查委托的目标是否为空,并且我想将其删除,并且我想在同一脚本中调用同一委托时唯一地抵抗委托。我怎样才能安全地使用它?这是我的源示例。
经理班
public class TestManager : MonoBehaviour
{
public Action TestDelegate;
// Use this for initialization
void Update ()
{
if (Input.GetKeyDown("space"))
{
if(null != TestDelegate)
{
TestDelegate();
}
}
}
}
对象类
public class WindosTest : MonoBehaviour {
[SerializeField]
TestManager _manager;
private void Awake()
{
_manager.TestDelegate += Test;
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown("d"))
{
GameObject.DestroyImmediate(this.gameObject);
}
}
void Test()
{
UnityEngine.Debug.LogError("test");
}
}
解决方案
这里的问题是使用 DestroyImmediate 而不是 Destroy。这两者之间的主要区别在于 Destroy 需要正确解构对象,这意味着它将在被销毁之前收到其 OnDisable() 回调(因此它有机会取消订阅委托)。
通常(不在编辑器中)出于安全考虑,最好调用 Destroy() 而不是 DestroyImmediate()。
如果你调用 Destroy(),你会得到正常的 OnDisable 回调,这意味着你可以:
void OnEnable()
{
_manager.TestDelegate += Test;
}
void OnDisable()
{
_manager.TestDelegate -= Test;
}
推荐阅读
- php - 如何使用相同的密码将 Laravel 用户验证为 wordpress 用户
- javascript - 数组中按字段的项目长度
- node.js - Node.js - Axios - 将文件上传到另一台服务器
- ios - 斯威夫特:我如何录制音频然后反向播放
- oauth - 如何处理我设计的网站上的 disallowed_useragent 错误?
- neo4j - 我的 neo4j 配置是什么?
- javascript - Webhook 似乎不起作用
- dynamic - 动态链接到产品类别
- c# - 在数据网格中显示用户 ID
- javascript - 错误!如何绕过/更改某些语法以缩小流程 - Javascript