我有一个类在场景层次结构中实例化几个统一游戏对象。这个类实现了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
}
}
答案 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)
嗯,我觉得你有点误解了IDisposable
和using
语句的用法。你不应该在任何地方实现IDisposable
只是为了摆脱一个对象 - 这是垃圾收集器角色,当一个对象被丢弃时它会更清楚。
IDisposable
和using
语句用作try/finally
语句(当然它在引擎盖下要复杂得多)并确保在对象被删除/解析之后立即执行不再使用了。它并不总是托管/非托管资源问题。
使用using
语句不会确保您的游戏对象将被处置。这一切都取决于是否有另一个指向它的对象。由于它看起来像一个根对象,我相信GC会尽可能长久地保留它。请注意,即使GC在您的对象上调用Dispose()
,只要它被引用,它将保留在特殊队列中,直到它被释放。
另一方面,如果GameObject
少于Game
,更多Object
,则您不应该考虑使用IDisposable
进行处置,只要它不以某种方式连接某些连接/文件/外部资源。一旦您的对象被视为垃圾,GC就会声明内存。请注意,IDisposable
是CLR对待有点不同的东西,并不总是可行的方式。
修改强>
根据您编辑的问题 - 基本上当对象超出范围时,您什么也不做 - 如果GC认为它是垃圾,它将被删除,并发生最接近的GC集合。这就是为什么C#被认为是托管语言以及为什么你不能自己释放内存的原因。