我通常使用委托进行回调。例如,我在统一脚本中的管理器中声明了动作委托,并在派生自Monobehaviuor的脚本中调用OnEnable时注册了委托,并取消了订阅。但是我知道,如果我在错误的时间反抗和反抗可能会很危险。例如,如果某人删除了对象。委托目标将为null。然后可以进行不需要的委托回调。 因此,当代理执行时,我想检查代理的目标是否为空,我想删除它,并且当同一脚本中调用相同的代理时,我想唯一地抵制代理。如何安全使用?这是我的原始示例。
经理阶层
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");
}
}
答案 0 :(得分:1)
这里的问题是使用DestroyImmediate而不是Destroy。两者之间的主要区别是Destroy要求对对象进行适当的解构,这意味着在销毁对象之前,它将收到其OnDisable()回调(因此它有机会取消委托)。
出于安全考虑,通常(不是在编辑器中)最好调用Destroy()而不是DestroyImmediate()。
如果调用Destroy(),将获得正常的OnDisable回调,这意味着您可以执行以下操作:
void OnEnable()
{
_manager.TestDelegate += Test;
}
void OnDisable()
{
_manager.TestDelegate -= Test;
}
答案 1 :(得分:0)
您已经在做,除非我误解了这个问题
如果要使其更短,请按以下步骤进行操作,但是由于已经在检查null,因此您的代码可以正常工作
TestDelegate?.Invoke();