为什么相同的一段代码运行在Editor上得到MissingReferenceException错误而在移动设备上则是NullReferenceException

来源:互联网 发布:安顺浪人网络官网 编辑:程序博客网 时间:2024/06/08 16:56

原文地址:https://support.unity3d.com/hc/en-us/articles/115000404563-Why-am-I-getting-MissingReferenceException-in-the-Editor-and-a-NullReferenceException-on-mobile-devices-when-running-the-same-piece-of-code-

症状

某个代码片段运行于Editor环境下抛出了MissingReferenceException,但是运行于移动设备上时抛出的是NullReferenceException。

原因

下面的示例代码随它在哪里执行(Editor或者Player)而抛出不同的导常:

using UnityEngine;using System.Collections;public class TestExceptions : MonoBehaviour {    GameObject myGameObject = null;    void Start ()    {        myGameObject = new GameObject("MyGameObject");        Destroy(myGameObject);        StartCoroutine(Test());    }    IEnumerator Test()    {        yield return new WaitForSeconds(2);        Debug.Log(myGameObject.name); // MissingReferenceException / NullReferenceException    }}

在本例中,MissingReferenceException仅在Editor环境下才会抛出,在Player环境则是NullReferenceException。这是因为Unity是一个C/C++引擎,所有实际关于该myGameObject的信息都是存储在C++那一边。

C#物体仅有东西就是一个指向本地物体的指针,因此Destroy(myGameObject)销毁了本地物体,而C#这边的托管物体依然存在,直到它不再被引用而销毁,并被垃圾回收器回收。

同样地,当一个MonoBehaviour在Editor上拥有一个字段,Unity并不是将这些字段设置成“真的”null值,而是一个“假的”null物体。这就允许Unity存储一些信息,当你在其上调用方法时提供给你更加上下文相关的信息,或者当你想获取物体的某个属性时。

如果没有这些手段,你仅能得到一个NullReferenceException,并且不知道到底是哪个GameObject的MonoBehaviour的字段是null。通过这种假null方法,Unity能在Inspector界面高亮GameObject,并且提供给你更多问题源的方向(在本例中,抛出了一个MissingReferenceException)。

Unity并不会在Player版本中保留这些信息,因为理应尽可能地优化,跑得越快越好,不该负面影响性能或者内存消耗。

解决方案

这是一个有意为之的行为特性。

更多信息

欲知更多信息,请查看下面的链接:

  • NullReferenceException是什么?
  • 自定义的==运算符,我们应该保留吗?
0 0
原创粉丝点击