IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> C#语法糖 (?) null空合并运算符对UnityEngine.Object类型不起作用 -> 正文阅读

[游戏开发]C#语法糖 (?) null空合并运算符对UnityEngine.Object类型不起作用

  1. var?a?=?new?GameObject("A");

  2. var?b?=?new?GameObject("B");

  3. Destroy(a);

  4. // Wait as mutch as you like before

  5. Debug.Log((a????b).name);?// It will give a MissingReferenceException

public GameObject c;
c?.gameObject.SetActive(false); // It will give a MissingReferenceException

原因

Unity对 == 运算符做了一些自以为是的反人类特殊处理。?

太长不看版目的:尽量不要报空,即便是真空了,我也包一层 ”假空“ 指向这个真空,而不是直接报真空。

详细版:

目的一:

当一个MonoBehaviour有字段时,仅在编辑器中[1],我们不会将这些字段设置为 "真正的null",而是设置为 "假null "对象。我们的自定义==操作符能够检查某些东西是否是这些假空对象之一,并采取相应的行为。虽然这是一个奇特的设置,但它允许我们在假空对象中存储信息,当你对它调用一个方法时,或者当你向该对象询问一个属性时,可以给你更多的上下文信息。如果没有这个技巧,你只会得到一个NullReferenceException,一个堆栈跟踪,但你不知道哪个GameObject的MonoBehaviour的字段是空的。有了这个技巧,我们可以在检查器中突出显示GameObject,也可以给你更多的指导。"看起来你正在访问这个MonoBehaviour中的一个未初始化的字段,使用检查器使这个字段指向某个东西"。


目的二有点复杂。

当你得到一个 "GameObject"[2]类型的c#对象时,它几乎什么都不包含。这是因为Unity是一个C/C++引擎。所有关于这个GameObject的实际信息(它的名字、它的组件列表、它的HideFlags等等)都在C++端。c#对象拥有的唯一东西是一个指向本地对象的指针。我们称这些c#对象为 "包装器对象"。??这些C++对象的生命周期,如GameObject和其他所有派生自UnityEngine.Object的对象,都是显式管理的。当你加载一个新的场景时,这些对象会被销毁。或者当你对它们调用Object.Destroy(myObject);时。c#对象的生命周期是用c#方式管理的,有一个垃圾收集器。这意味着有可能有一个仍然存在的c#包装对象,它包装了一个已经被销毁的c++对象。如果你将这个对象与null进行比较,在这种情况下,我们的自定义==操作符将返回 "true",尽管实际的c#变量实际上并不是真的null。

缺点? ?


虽然这两个用例相当合理,但自定义的null检查也带来了一堆缺点

1. 它是反直觉的。
2. 将两个UnityEngine.Objects相互比较或与null比较的速度比你想象的要慢。
3. 自定义的==运算符不是线程安全的,所以你不能在主线程之外比较对象。(这个问题我们可以解决)。
4. 它的行为与??操作符不一致,后者也做一个空值检查,但是那个操作符做的是纯c#的空值检查,不能被绕过来调用我们的自定义空值检查

考虑到所有这些优点和缺点,如果我们从头开始构建我们的API,我们会选择不做一个自定义的空值检查,而是有一个myObject.destroy属性,你可以用它来检查对象是否已经死亡,而只是忍受这样一个事实:如果你真的在一个空字段上调用一个函数,我们不能再给出更好的错误信息。

我们正在考虑的是,我们是否应该改变这一点。这是我们在 "修复和清理旧事物 "和 "不破坏旧项目 "之间找到正确平衡的永无止境的探索的一个步骤。在这种情况下,我们想知道你的想法。对于Unity5,我们一直在努力使Unity能够自动更新你的脚本(关于这一点,在随后的博文中会有更多介绍)。不幸的是,对于这种情况,我们将无法自动升级你的脚本。(因为我们无法区分 "这是一个实际想要旧行为的旧脚本",和 "这是一个实际想要新行为的新脚本")。

我们倾向于 "移除自定义的==运算符",但又犹豫不决,因为这将改变你的项目目前所做的所有空值检查的意义。对于对象不是 "真正的null "而是一个被破坏的对象的情况,null检查过去是返回真,如果我们改变这个,它将返回假。如果你想检查你的变量是否指向一个被破坏的对象,你需要将代码改为检查 "if (myObject.destroy) {}"。我们对此有点紧张,因为如果你没有读过这篇博文,而且很可能如果你读过了,就很容易意识不到这种改变后的行为,尤其是大多数人根本没有意识到这种自定义的空值检查的存在[3]

索引

[1] 我们只在编辑器中这样做。这就是为什么当你调用GetComponent()查询一个不存在的组件时,你会看到C#的内存分配发生,因为我们在新分配的假空对象中生成了这个自定义的警告字符串。这种内存分配不会发生在内置游戏中。这是一个很好的例子,如果你要对你的游戏进行剖析,你应该总是对实际的独立玩家或移动玩家进行剖析,而不是对编辑器进行剖析,因为我们在编辑器中做了很多额外的安全性/安全/使用检查,以使你的生活更容易,但却牺牲了一些性能。当对性能和内存分配进行剖析时,永远不要对编辑器进行剖析,总是对构建的游戏进行剖析。
[2] 这不仅适用于GameObject,而且适用于所有从UnityEngine.Object派生出来的东西。
[3] 有趣的故事。我在优化GetComponent<T>()性能时遇到了这个问题,在为变换组件实现一些缓存时,我没有看到任何性能上的好处。然后@jonasechterhoff看了看这个问题,也得出了同样的结论。缓存代码看起来像这样。

private Transform m_CachedTransform
public Transform transform
{
  get
  {
    if (m_CachedTransform == null)
      m_CachedTransform = InternalGetTransform();
    return m_CachedTransform;
  }
}

结果我们的两位工程师发现,空值检查的成本比预期的要高,这也是没有从缓存中看到任何速度优势的原因。这导致了 "如果连我们都忽略了它,那么我们有多少用户会忽略它呢?",这导致了这篇博文:)

C# (??) null-coalescing operator does not work for UnityEngine.Object types - Unity Forum

Custom == operator, should we keep it? | Unity Blog

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-01-29 23:24:16  更:2022-01-29 23:24:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:31:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码