我来自C ++背景,无法理解IDisposable
对象的观点(以及.NET中许多其他内容的要点)。为什么首先需要Dispose
函数?无论它做什么,为什么不在类的析构函数中做到这一点?我理解它可以清理托管资源,但这不是析构函数应该做的吗?我明白了
Using ( var obj = new SomeIDisposableObject )
{
// ...
}
相当于
var obj = new SomeIDisposableObject;
// ...
obj.Dispose();
但是如何保存任何打字?如果C#有一个垃圾收集器,那么为什么我们会担心处理资源呢?
是IDisposable
/ Using
/等。 Skeet认可的概念?他怎么看待它?
答案 0 :(得分:7)
tableView(tableView: UITableView, numberOfRowsInSection section: Int)
numberOfSectionsInTableView(tableView: UITableView)
tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
没什么特别的。它只是一个让你拥有IDisposable
功能的界面。 Dispose()
无法清除任何内容或销毁对象。如果该函数什么都不做,对IDisposable
的调用什么也不做。
使用Dispose()
是模式。它是如此重要以至于它获得了自己的语言结构(IDisposable
块),但它只是一种模式。
与析构函数的区别在于,在.NET中,析构函数是非确定性的。你永远不知道垃圾收集器什么时候会收集你的对象。你甚至不知道它是否会(不像在C ++中使用using
,这是确定性的。)
所以delete
是确定性释放不需要的引用(以及释放非托管资源)。 "处理"在调用IDisposable
之后,对象将保留在内存中,直到垃圾收集器决定收集它(此时,将调用"析构函数"除非您明确告诉它不要),如果它决定了。
这是使用"析构函数"的主要区别。 (或终结者,因为它们在C#中调用)。
至于为什么我们需要它:
Dispose
)。null
应用程序中的每个控件或位图都使用Windows.Forms
,这是非托管的。如果您不发布这些资源,则可以轻松地在Windows中使用任何大型应用程序时达到句柄限制。此外,如果您需要与任何非.NET API的互操作性,您更有可能必须分配非托管内存(例如,使用Win32 handler
),这需要在某些内容中释放point:该点通常 Marshal.AllocHGlobal
Dispose()
IDisposable
函数,必须明确调用(或使用using
块)。对于using
块,它更相当于:
var myObject = new MyDisposableClass();
try
{
...
}
finally {
myObject.Dispose();
}
所以确实可以节省打字
答案 1 :(得分:1)
使用using
块并不只调用.Dispose
方法;当你离开街区时它会调用.Dispose方法,但是你留下它。因此,如果您的代码崩溃,它仍将调用Dispose。实际代码将更接近:
try
{
var obj = new SomeIDisposableObject;
// ...
}
catch (exception ex)
{
}
finally
{
obj.Dispose();
}
此外,析构函数并不总是在您期望的时候触发。我已经有一些错误,在程序显然退出后调用析构函数,并尝试访问不再存在的资源。由于你不会know
何时会被召唤,因此很难解决这个问题。