【解决】MissingReferenceException: The object of type ‘GameObject‘ has been destroyed 观察者模式 监听物体被销毁

MissingReferenceException: The object of type ‘Text’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
该情况发生于我的观察者模式重新加载当前场景时 监听的物体被销毁
如上所示错误,通过分析,定位到错误是在观察者模式使用事件分发器注册监听 消息。其内部方式使用 委托订阅方式进行,在重加载场景时,unity调用Destory()生命周期函数 此时监听挂载没有被清楚。或者说该监听需要的gameobject 实例重新加载时销毁掉
观察者模式地址
在这里插入图片描述
如下图所示 监听挂载后 在重新加载的过程中没有Remove掉;
在这里插入图片描述
需要在脚本销毁时OnDestroy()生命周期中,调用写好的RemoveEventListener函数(unity在重新加载当前场景时时,会调用该生命周期函数);
在这里插入图片描述
该函数如下所示

public static void RemoveEventListener(string name,UnityAction<object> action)
    {
        if (eventDic.ContainsKey(name))
        {
            eventDic[name] -= action;
        }
        Debug.Log("RemoveEventListener");
    }

### 解决MissingReferenceException错误的方法 当遇到`MissingReferenceException`错误时,通常是因为尝试访问已经被销毁的对象。在这种情况下,涉及到Unity中的`Transform`组件被销毁后仍然被访问的问题[^1]。 #### 错误原因分析 在Unity引擎中,如果一个游戏对象(GameObject)及其关联的组件(如`Transform`)已被销毁,而脚本仍在试图访问这些已销毁的组件,则会抛出`MissingReferenceException`异常。这种问题常见于协程、定时器或其他异步操作场景下,在这些场景中,可能由于生命周期管理不当而导致对无效引用的操作[^2]。 #### 防止访问已销毁对象的解决方案 为了防止此类错误的发生,可以采取以下几种方法: 1. **检查对象是否为空** 在每次访问`Transform`之前,先验证其所属的游戏对象是否未被销毁。可以通过简单判断来实现这一点: ```csharp if (transform != null && transform.gameObject.activeInHierarchy) { // 安全地执行与Transform相关的逻辑 } ``` 2. **取消挂起的任务或协程** 如果存在依赖特定`Transform`实例运行的协程或者任务,应该确保在销毁该游戏对象前停止它们。例如: ```csharp private void OnDestroy() { StopAllCoroutines(); // 停止当前类下的所有正在运行的协程 } ``` 3. **使用事件驱动模型替代硬编码引用** 考虑采用观察者模式或者其他松耦合的设计方式代替直接持有其他物体的引用。这样即使目标物体消失也不会影响到源代码的行为逻辑[^3]。 4. **延迟销毁机制** 对某些特殊需求可考虑引入短暂延时后再真正移除资源的方式,给系统足够时间完成必要的清理工作。比如利用`Destroy(gameObject, delayTime)`函数设置合理的等待周期再彻底释放内存空间[^4]。 通过上述措施能够有效减少甚至完全规避因意外调用已经不存在的数据结构所引发的各种潜在风险。 ```csharp using UnityEngine; public class SafeAccessExample : MonoBehaviour { public Transform targetTransform; void Update() { if (targetTransform != null && targetTransform.gameObject.activeInHierarchy) { Vector3 position = targetTransform.localPosition; Debug.Log("Local Position: " + position); } else { Debug.LogWarning("Target Transform is either null or inactive."); } } void OnDestroy() { StopAllCoroutines(); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值