public class GameObject
{
Vector2 position;
Vector2 scale;
Color color;
Texture2D atlas_reference;
Rectangle source_rectangle;
public GameObject()
{
//...
// atlas_reference is a reference to the texture loaded in "LoadContent" in the main XNA's
// loop
}
// ...
// ...
// ...
public void Update(GameTime dt)
{
//...
}
public void Draw(SpriteBatch spritebatch)
{
//...
}
}
我应该实现Dispose方法吗?
public void Dispose()
{
atlas_reference.Dispose(); // ?
}
我认为不,因为我会把方法放在加载的地方。在这个课程中,它只是一个参考。我错了吗?
也许我只需要这样做:atlas_reference = null;
?
public class GameWorld
{
List<GameObject> game_objects;
const int obj_number = 1000;
public GameWorld()
{
//...
for (int i = 0; i < 1000; ++i)
game_objects[i] = new GameObject();
// ...
}
// ...
// ...
// ...
public void Update(GameTime dt)
{
//... loop through the list and update every one
}
public void Draw(SpriteBatch spritebatch)
{
//... loop through the list and draw every one
}
}
这里我认为我应该实现Dispose,因为我正在生成一些对象,所以:
public void Dispose()
{
for (int i = obj_number; i >= 0; --i)
game_objects[i].Dispose();
}
但是我知道GameObject的dispose方法没有处理任何东西,所以我应该实现它吗?
正确的做法是什么?
答案 0 :(得分:2)
根据MSDN,您只需实施IDisposable即可发布非托管资源。 XNA负责内容管道,因此您无需担心Texture2D。
您的对象所持有的引用将在销毁时被取消,因此您也不必担心。 C#使用引用计数垃圾收集器,因此一旦计数达到0,它将自动收集。
直接引用它:
只有当您的类型直接使用非托管资源时,才应实现IDisposable。
答案 1 :(得分:2)
说你和我是好朋友,有一天你来找我并要求借我的割草机。我当然同意;毕竟,你是我的朋友,我希望你能以适当的尊重对待我的财产。
几天后我需要修剪草坪,所以我来到你家,请你把割草机归还。 “抱歉,”你说,“我做不到。”
“为什么不呢?”我问。
“好吧,我把它从棚子后面拿出来放火了。”这是你在第一个例子中提出的建议。您正在asset_reference
对象中加载Game
,可能是通过其内容管理器。在XNA中,内容管理器拥有其加载的资产。它将它们存储在内部缓存中,这样它就不必在每次请求时重新加载它们。所以,如果你这样做:
var resource = content.Load<Foo>("bar").Baz();
resource.Dispose();
content.Load<Foo>("bar").Baz();
对Baz()
的第二次调用几乎肯定会抛出ObjectDisposedException
!你正试图用你疯狂的邻居留下的烧毁的割草机割草坪。
对象应该管理他们拥有的资源的生命周期。就像你没有权利用我的割草机火炬一样,另一个班级无权为提供的资源进行火炬传递,除非你明确转移了资源的所有权。
第二个例子更接近我认为合适的 - 一个对象正在处理它创建的资源并因此拥有 - 但是如果你知道Dispose()
上的GameObject
方法没有做到做什么,然后为什么要实现IDisposable
?
答案 2 :(得分:1)
据我了解,如果您的班级包含IDisposable
成员,您还应该让您的班级实施IDisposable
并在班级Dispose()
上调用Dispose()
{{1}} 1}}方法。