1

Unity3D 中的 C# 脚本环境(在 Mono 下运行)在销毁对象时具有良好的行为。所有指向被破坏对象的引用都会自动变为 null :

    GameObject ref1 = (GameObject)Instantiate(obj);
    GameObject ref2 = ref1;

    if (ref1 != null)
        Debug.Log("ref1 is not null");

    DestroyImmediate(ref1);

    if (ref1 == null)
        Debug.Log("ref1 is null");

    if (ref2 == null)
        Debug.Log("ref2 is null");    

输出 :

    ref1 is not null
    ref1 is null
    ref2 is null

关于如何实现这一目标的任何想法?

谢谢

4

6 回答 6

3

也许相等运算符已被覆盖?这可以解释你的评论:“只要发现 ref1 和 ref2 不是 GameObject 而是 System.Object,那么它就行不通了。”

于 2010-01-24T21:49:33.380 回答
2

Unity3D(ab)可能使用运算符重载+某种内部标志,例如bool isDeleted;当在函数isDeleted中设置为时,然后对yield进行相等测试。trueDestroyImmediatenulltrue

于 2010-01-24T21:55:10.147 回答
1

您不能在 C# 中使用按值调用参数执行此操作。您还必须在调用站点使用ref需要关键字的参数。ref

事实上,.NET 中没有可访问但已销毁(即解除分配)的托管对象的有用概念(好吧,忽略WeakReference哪个并不重要)。该对象要么不可访问,要么无法被销毁。

于 2010-01-24T21:39:19.703 回答
0

这在“常规”.NET 中是不可能的,这不是 CLR 的工作方式。

于 2010-01-24T21:40:10.590 回答
0

虽然是一个有趣的学术挑战,但从技术角度来看并不值得追求。您从错误的角度看待这个问题 - CLR 为您管理对象的生命周期。将所有“变量”设置为 null 的唯一方法是使用“ref”参数修饰符将所有变量传递给您的销毁方法。除非您打算在单个方法中编写整个程序,否则您会找错树。结构正确的类和方法将确保超出范围的变量被“清空”,释放目标对象以进行垃圾回收。

于 2010-01-24T21:43:27.713 回答
0

您可以添加一个中间类(代理)来保存对实际类的引用。

你所有的 refs 都将指向这个新的 GameObjectProxy。这将提供与 GameObject 相同的 API,并将对其的任何调用转发到底层 GameObject 对象。

GameObjectProxy 还将提供额外的方法 - 销毁底层 GameObject,并查询 GameObject 是否为空。(如果你想变得非常邪恶,这些可能会被内置到 operator= 和 operator== 中)

请记住,这种方法可能会降低性能,因为对 GameObject 的每次调用都必须通过代理重定向。它也有点邪恶——它会让那些期望他们的引用表现“正常”的程序员感到困惑。

于 2010-01-24T22:03:01.850 回答