Unity游戏对象是托管资源还是非托管资源?

时间:2015-09-07 11:15:39

标签: c# unity3d idisposable

我有一个类在场景层次结构中实例化几个统一游戏对象。这个类实现了IDisposable。我应该处理这些游戏对象,因为它们是托管或非托管资源吗?

我关注Dispose pattern,那么我应该在哪里调用GameObject.Destroy(myGameObject)这样的调用?

谢谢

修改: 好吧,假设我想要在超出范围时销毁这个类实例化的游戏对象。那你怎么办?

编辑2: 我正在测试处置。我找到了解决方案。它不会自动工作,因为GameObject.Destroy(myGameObject)无法从不同的线程调用。它会抛出一个错误CompareBaseObjectsInternal。所以,当不再需要时,我调用myClass.Dispose()。我是否将Unity GameObject处理为托管或非托管似乎无关紧要。

myMain()
{
    DisposeTestClass test = new DisposeTestClass();
    //...
    test.Dispose();
}


class DisposeTestClass : System.IDisposable
{

    public GameObject uselessGameobject { get; private set; }

    public DisposeTestClass()
    {           
        uselessGameobject = new GameObject("Useless gameobject");
    }

    #region IDisposable
    private bool _disposed;

    ~DisposeTestClass()
    {
        Debug.Log("~DisposeTestClass()");

        this.Dispose(false);
    }

    public void Dispose()
    {
        Debug.Log("Dispose()");

        this.Dispose(true);
        System.GC.SuppressFinalize(this);

    }

    protected virtual void Dispose(bool disposing)
    {
        Debug.Log("Dispose(bool)");

        if(_disposed)
        {
            Debug.Log("Disposed. Return.");
            return;
        }           

        if(disposing)
        {
            Debug.Log("Disposing of managed resources...");

            // clean up managed resources
            /*
            if(uselessGameobject != null)
            {
                GameObject.Destroy(uselessGameobject);
                Debug.Log("Game object destroyed.");
            }
            else
            {
                Debug.Log("Game object is null.");
            }*/

        }

        Debug.Log("Cleaning up unmanaged resources...");
        // clean up unmanaged resources

        if(uselessGameobject != null)
        {
            GameObject.Destroy(uselessGameobject);
            Debug.Log("Game object destroyed.");
        }
        else
        {
            Debug.Log("Game object is null.");
        }

        // set the flag
        Debug.Log("Setting the disposed flag.");
        this._disposed = true;
    }
    #endregion

}

}

2 个答案:

答案 0 :(得分:2)

不,你不应该实现IDisposable。但你可以:)。

“所以我应该在哪里调用GameObject.Destroy(myGameObject)”并且当你想要销毁你的对象时?实际上,无论你是否调用myContainer.Dispose()或GameObject.Destroy(gObj)都无关紧要。

为您实现IDisposable的唯一原因是编写“方便”的代码,如:

using(var container = new MyContainer())
using(var somethingElse = new MyObject())
{
    \\Logic for container and somethingElse 
}

但在Unity中这没有任何意义。我很难想象在更新游戏对象中创建然后销毁的情况。

答案 1 :(得分:1)

嗯,我觉得你有点误解了IDisposableusing语句的用法。你不应该在任何地方实现IDisposable只是为了摆脱一个对象 - 这是垃圾收集器角色,当一个对象被丢弃时它会更清楚。

IDisposableusing语句用作try/finally语句(当然它在引擎盖下要复杂得多)并确保在对象被删除/解析之后立即执行不再使用了。它并不总是托管/非托管资源问题。

使用using语句不会确保您的游戏对象将被处置。这一切都取决于是否有另一个指向它的对象。由于它看起来像一个根对象,我相信GC会尽可能长久地保留它。请注意,即使GC在您的对象上调用Dispose(),只要它被引用,它将保留在特殊队列中,直到它被释放。

另一方面,如果GameObject少于Game,更多Object,则您不应该考虑使用IDisposable进行处置,只要它不以某种方式连接某些连接/文件/外部资源。一旦您的对象被视为垃圾,GC就会声明内存。请注意,IDisposable是CLR对待有点不同的东西,并不总是可行的方式。

修改

根据您编辑的问题 - 基本上当对象超出范围时,您什么也不做 - 如果GC认为它是垃圾,它将被删除,并发生最接近的GC集合。这就是为什么C#被认为是托管语言以及为什么你不能自己释放内存的原因。